diff options
author | Jean-Baptiste Queru <jbq@google.com> | 2013-02-08 15:14:04 -0800 |
---|---|---|
committer | Jean-Baptiste Queru <jbq@google.com> | 2013-02-08 15:14:04 -0800 |
commit | 9edc8f6b58f71ec510ba36b838f115718d9a174d (patch) | |
tree | 06f6df92024fa534ff27e1c0b5fc8b2002848093 /java | |
parent | b56ea2a18f232d79481e778085fd64e8ae486fc3 (diff) | |
download | idea-9edc8f6b58f71ec510ba36b838f115718d9a174d.tar.gz |
Snapshot of commit 84dc01e773388c2c72a1fc437f313dd5747e7809
from branch master of git://git.jetbrains.org/idea/community.git
Diffstat (limited to 'java')
407 files changed, 6895 insertions, 3146 deletions
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/PropertyFileGeneratorImpl.java b/java/compiler/impl/src/com/intellij/compiler/ant/PropertyFileGeneratorImpl.java index ab93b32dbe35..f7ee1bcbfb14 100644 --- a/java/compiler/impl/src/com/intellij/compiler/ant/PropertyFileGeneratorImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/ant/PropertyFileGeneratorImpl.java @@ -39,63 +39,68 @@ import java.util.Set; * Date: Nov 27, 2004 */ public class PropertyFileGeneratorImpl extends PropertyFileGenerator { - /** - * List of the properties - */ - private final List<Pair<String, String>> myProperties = new ArrayList<Pair<String, String>>(); + /** + * List of the properties + */ + private final List<Pair<String, String>> myProperties = new ArrayList<Pair<String, String>>(); - /** - * A constctor that extracts all neeed properties for ant build from the project. - * - * @param project a project to examine - * @param genOptions generation options - */ - public PropertyFileGeneratorImpl(Project project, GenerationOptions genOptions) { - // path variables - final PathMacros pathMacros = PathMacros.getInstance(); - final Set<String> macroNamesSet = pathMacros.getUserMacroNames(); - if (macroNamesSet.size() > 0) { - final String[] macroNames = ArrayUtil.toStringArray(macroNamesSet); - Arrays.sort(macroNames); - for (final String macroName : macroNames) { - addProperty(BuildProperties.getPathMacroProperty(macroName), pathMacros.getValue(macroName)); - } - } - // jdk homes - if (genOptions.forceTargetJdk) { - final Sdk[] usedJdks = BuildProperties.getUsedJdks(project); - for (Sdk jdk : usedJdks) { - if (jdk.getHomeDirectory() == null) { - continue; - } - final File homeDir = BuildProperties.toCanonicalFile(VfsUtil.virtualToIoFile(jdk.getHomeDirectory())); - addProperty(BuildProperties.getJdkHomeProperty(jdk.getName()), homeDir.getPath().replace(File.separatorChar, '/')); - } - } - // generate idea.home property - if (genOptions.isIdeaHomeGenerated()) { - addProperty(BuildProperties.PROPERTY_IDEA_HOME, PathManager.getHomePath()); + /** + * A constctor that extracts all neeed properties for ant build from the project. + * + * @param project a project to examine + * @param genOptions generation options + */ + public PropertyFileGeneratorImpl(Project project, GenerationOptions genOptions) { + // path variables + final PathMacros pathMacros = PathMacros.getInstance(); + final Set<String> macroNamesSet = pathMacros.getUserMacroNames(); + if (macroNamesSet.size() > 0) { + final String[] macroNames = ArrayUtil.toStringArray(macroNamesSet); + Arrays.sort(macroNames); + for (final String macroName : macroNames) { + addProperty(BuildProperties.getPathMacroProperty(macroName), pathMacros.getValue(macroName)); + } + } + // jdk homes + if (genOptions.forceTargetJdk) { + final Sdk[] usedJdks = BuildProperties.getUsedJdks(project); + for (Sdk jdk : usedJdks) { + if (jdk.getHomeDirectory() == null) { + continue; } - ChunkBuildExtension.generateAllProperties(this, project, genOptions); + final File homeDir = BuildProperties.toCanonicalFile(VfsUtil.virtualToIoFile(jdk.getHomeDirectory())); + addProperty(BuildProperties.getJdkHomeProperty(jdk.getName()), homeDir.getPath().replace(File.separatorChar, '/')); + } + } + // generate idea.home property + if (genOptions.isIdeaHomeGenerated()) { + addProperty(BuildProperties.PROPERTY_IDEA_HOME, PathManager.getHomePath()); } - public void addProperty(String name, String value) { - myProperties.add(new Pair<String, String>(name, value)); + if (genOptions.enableFormCompiler) { + addProperty(BuildProperties.PROPERTY_INCLUDE_JAVA_RUNTIME_FOR_INSTRUMENTATION, genOptions.forceTargetJdk? "false" : "true"); } - @Override - public void generate(PrintWriter out) throws IOException { - boolean isFirst = true; - for (final Pair<String, String> pair : myProperties) { - if (!isFirst) { - crlf(out); - } - else { - isFirst = false; - } - out.print(StringUtil.escapeProperty(pair.getFirst(), true)); - out.print("="); - out.print(StringUtil.escapeProperty(pair.getSecond(), false)); - } + ChunkBuildExtension.generateAllProperties(this, project, genOptions); + } + + public void addProperty(String name, String value) { + myProperties.add(new Pair<String, String>(name, value)); + } + + @Override + public void generate(PrintWriter out) throws IOException { + boolean isFirst = true; + for (final Pair<String, String> pair : myProperties) { + if (!isFirst) { + crlf(out); + } + else { + isFirst = false; + } + out.print(StringUtil.escapeProperty(pair.getFirst(), true)); + out.print("="); + out.print(StringUtil.escapeProperty(pair.getSecond(), false)); } + } } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 568bb42b28a0..d0518ba688e8 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -521,11 +521,10 @@ public class CompileDriver { @Override public void handleFailure(UUID sessionId, CmdlineRemoteProto.Message.Failure failure) { - compileContext.addMessage(CompilerMessageCategory.ERROR, failure.getDescription(), null, -1, -1); - final String trace = failure.getStacktrace(); + compileContext.addMessage(CompilerMessageCategory.ERROR, failure.hasDescription()? failure.getDescription() : "", null, -1, -1); + final String trace = failure.hasStacktrace()? failure.getStacktrace() : null; if (trace != null) { LOG.info(trace); - System.out.println(trace); } compileContext.putUserData(COMPILE_SERVER_BUILD_STATUS, ExitStatus.ERRORS); } @@ -672,8 +671,12 @@ public class CompileDriver { if (message != null) { compileContext.addMessage(message); } - if (!executeCompileTasks(compileContext, true)) { - COMPILE_SERVER_BUILD_STATUS.set(compileContext, ExitStatus.CANCELLED); + + final boolean beforeTasksOk = executeCompileTasks(compileContext, true); + + final int errorCount = compileContext.getMessageCount(CompilerMessageCategory.ERROR); + if (!beforeTasksOk || errorCount > 0) { + COMPILE_SERVER_BUILD_STATUS.set(compileContext, errorCount > 0? ExitStatus.ERRORS : ExitStatus.CANCELLED); return; } @@ -699,7 +702,9 @@ public class CompileDriver { } if (!executeCompileTasks(compileContext, false)) { COMPILE_SERVER_BUILD_STATUS.set(compileContext, ExitStatus.CANCELLED); - return; + } + if (compileContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + COMPILE_SERVER_BUILD_STATUS.set(compileContext, ExitStatus.ERRORS); } } } @@ -709,7 +714,7 @@ public class CompileDriver { finally { CompilerCacheManager.getInstance(myProject).flushCaches(); - final long duration = notifyCompilationCompleted(compileContext, callback, COMPILE_SERVER_BUILD_STATUS.get(compileContext)); + final long duration = notifyCompilationCompleted(compileContext, callback, COMPILE_SERVER_BUILD_STATUS.get(compileContext), true); CompilerUtil.logDuration( "\tCOMPILATION FINISHED (BUILD PROCESS); Errors: " + compileContext.getMessageCount(CompilerMessageCategory.ERROR) + @@ -717,15 +722,6 @@ public class CompileDriver { compileContext.getMessageCount(CompilerMessageCategory.WARNING), duration ); - - // refresh on output roots is required in order for the order enumerator to see all roots via VFS - final Set<File> outputs = new HashSet<File>(); - for (final String path : CompilerPathsEx.getOutputPaths(ModuleManager.getInstance(myProject).getModules())) { - outputs.add(new File(path)); - } - if (!outputs.isEmpty()) { - LocalFileSystem.getInstance().refreshIoFiles(outputs, true, false, null); - } } } }; @@ -837,7 +833,7 @@ public class CompileDriver { if (!myProject.isDisposed()) { writeStatus(new CompileStatus(CompilerConfigurationImpl.DEPENDENCY_FORMAT_VERSION, wereExceptions, vfsTimestamp), compileContext); } - final long duration = notifyCompilationCompleted(compileContext, callback, status); + final long duration = notifyCompilationCompleted(compileContext, callback, status, false); CompilerUtil.logDuration( "\tCOMPILATION FINISHED; Errors: " + compileContext.getMessageCount(CompilerMessageCategory.ERROR) + @@ -850,8 +846,24 @@ public class CompileDriver { } /** @noinspection SSBasedInspection*/ - private long notifyCompilationCompleted(final CompileContextImpl compileContext, final CompileStatusNotification callback, final ExitStatus _status) { + private long notifyCompilationCompleted(final CompileContextImpl compileContext, + final CompileStatusNotification callback, + final ExitStatus _status, + final boolean refreshOutputRoots) { final long duration = System.currentTimeMillis() - compileContext.getStartCompilationStamp(); + if (refreshOutputRoots) { + // refresh on output roots is required in order for the order enumerator to see all roots via VFS + final Set<File> outputs = new HashSet<File>(); + for (final String path : CompilerPathsEx.getOutputPaths(ModuleManager.getInstance(myProject).getModules())) { + outputs.add(new File(path)); + } + if (!outputs.isEmpty()) { + final ProgressIndicator indicator = compileContext.getProgressIndicator(); + indicator.setText("Synchronizing output directories..."); + LocalFileSystem.getInstance().refreshIoFiles(outputs, false, false, null); + indicator.setText(""); + } + } SwingUtilities.invokeLater(new Runnable() { public void run() { int errorCount = 0; diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java index f53e4df68e67..6cbb54b2151d 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java @@ -18,8 +18,10 @@ package com.intellij.compiler.impl; import com.intellij.compiler.CompilerWorkspaceConfiguration; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.*; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; @@ -37,6 +39,7 @@ import java.util.List; * Date: 9/5/12 */ public class FileProcessingCompilerAdapterTask implements CompileTask{ + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.FileProcessingCompilerAdapterTask"); private final FileProcessingCompiler myCompiler; public FileProcessingCompilerAdapterTask(FileProcessingCompiler compiler) { @@ -104,18 +107,27 @@ public class FileProcessingCompilerAdapterTask implements CompileTask{ CompilerUtil.runInContext(context, CompilerBundle.message("progress.updating.caches"), new ThrowableRunnable<IOException>() { public void run() throws IOException{ final List<VirtualFile> vFiles = new ArrayList<VirtualFile>(processed.length); - for (FileProcessingCompiler.ProcessingItem item : processed) { - vFiles.add(item.getFile()); - } + final List<Pair<FileProcessingCompiler.ProcessingItem, ValidityState>> toUpdate = new ArrayList<Pair<FileProcessingCompiler.ProcessingItem, ValidityState>>(processed.length); + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + for (FileProcessingCompiler.ProcessingItem item : processed) { + vFiles.add(item.getFile()); + toUpdate.add(Pair.create(item, item.getValidityState())); + } + } + }); LocalFileSystem.getInstance().refreshFiles(vFiles); - for (FileProcessingCompiler.ProcessingItem item : processed) { - cache.update(item.getFile(), item.getValidityState()); + + for (Pair<FileProcessingCompiler.ProcessingItem, ValidityState> pair : toUpdate) { + cache.update(pair.getFirst().getFile(), pair.getSecond()); } } }); } catch (IOException e) { - throw new RuntimeException(e); + context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1); + LOG.info(e); } return true; } diff --git a/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java index 21863bd4866e..57e1ad71c8f7 100644 --- a/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java +++ b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java @@ -19,6 +19,7 @@ import com.intellij.compiler.CompilerConfiguration; import com.intellij.compiler.CompilerConfigurationImpl; import com.intellij.compiler.CompilerWorkspaceConfiguration; import com.intellij.compiler.MalformedPatternException; +import com.intellij.compiler.server.BuildManager; import com.intellij.openapi.compiler.CompilerBundle; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.options.Configurable; @@ -129,6 +130,9 @@ public class CompilerUIConfigurable implements SearchableConfigurable, Configura if (wasUsingExternalMake != workspaceConfiguration.USE_COMPILE_SERVER) { myProject.getMessageBus().syncPublisher(ExternalBuildOptionListener.TOPIC).externalBuildOptionChanged(workspaceConfiguration.USE_COMPILE_SERVER); } + if (workspaceConfiguration.USE_COMPILE_SERVER) { + BuildManager.getInstance().clearState(myProject); + } } private static void applyResourcePatterns(String extensionString, final CompilerConfigurationImpl configuration) diff --git a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java index 527b627b0172..7c101e8ee30f 100644 --- a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java +++ b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java @@ -135,6 +135,7 @@ public class CompilerTask extends Task.Backgroundable { try { try { + final Application app = ApplicationManager.getApplication(); while (!acquired) { acquired = semaphore.tryAcquire(500, TimeUnit.MILLISECONDS); if (indicator.isCanceled()) { @@ -142,6 +143,9 @@ public class CompilerTask extends Task.Backgroundable { // let compile work begin in order to stop gracefuly on cancel event break; } + if (app.isDispatchThread()) { + UIUtil.dispatchAllInvocationEvents(); + } } } catch (InterruptedException ignored) { diff --git a/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java index 05bfe722e3ba..bc50140789d1 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java @@ -110,7 +110,11 @@ class AutoMakeMessageHandler extends DefaultMessageHandler { @Override public void handleFailure(UUID sessionId, CmdlineRemoteProto.Message.Failure failure) { - final String msg = "Auto make failure: " + failure.getDescription(); + String descr = failure.hasDescription() ? failure.getDescription() : null; + if (descr == null) { + descr = failure.hasStacktrace()? failure.getStacktrace() : ""; + } + final String msg = "Auto make failure: " + descr; CompilerManager.NOTIFICATION_GROUP.createNotification(msg, MessageType.INFO); ProblemsView.SERVICE.getInstance(myProject).addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.ERROR, msg), sessionId); } diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index a819b47121bd..9d9aafba7b31 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -27,15 +27,17 @@ import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.configurations.RunProfile; import com.intellij.execution.process.*; import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.execution.ui.RunContentManager; import com.intellij.ide.PowerSaveMode; import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.PathMacros; -import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.*; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; @@ -51,6 +53,7 @@ import com.intellij.openapi.roots.ModuleRootAdapter; import com.intellij.openapi.roots.ModuleRootEvent; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.ShutDownTracker; @@ -65,6 +68,8 @@ import com.intellij.openapi.vfs.newvfs.BulkFileListener; import com.intellij.openapi.vfs.newvfs.events.VFileEvent; import com.intellij.util.Alarm; import com.intellij.util.Function; +import com.intellij.util.SmartList; +import com.intellij.util.concurrency.Semaphore; import com.intellij.util.concurrency.SequentialTaskExecutor; import com.intellij.util.io.storage.HeavyProcessLatch; import com.intellij.util.messages.MessageBusConnection; @@ -91,6 +96,7 @@ import org.jetbrains.jps.api.RequestFuture; import org.jetbrains.jps.cmdline.BuildMain; import org.jetbrains.jps.cmdline.ClasspathBootstrap; import org.jetbrains.jps.incremental.Utils; +import org.jetbrains.jps.model.serialization.JpsGlobalLoader; import javax.tools.*; import java.io.File; @@ -113,16 +119,20 @@ import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage * Date: 9/6/11 */ public class BuildManager implements ApplicationComponent{ + public static final Key<Boolean> ALLOW_AUTOMAKE = Key.create("_allow_automake_when_process_is_active_"); + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.server.BuildManager"); + private static final String COMPILER_PROCESS_JDK_PROPERTY = "compiler.process.jdk"; private static final String SYSTEM_ROOT = "compile-server"; private static final String LOGGER_CONFIG = "log.xml"; private static final String DEFAULT_LOGGER_CONFIG = "defaultLogConfig.xml"; - private static final int MAKE_TRIGGER_DELAY = 3 * 1000 /*3 seconds*/; + private static final int MAKE_TRIGGER_DELAY = 300 /*300 ms*/; + private static final int DOCUMENT_SAVE_TRIGGER_DELAY = 1500 /*1.5 sec*/; private final boolean IS_UNIT_TEST_MODE; private static final String IWS_EXTENSION = ".iws"; private static final String IPR_EXTENSION = ".ipr"; private static final String IDEA_PROJECT_DIR_PATTERN = "/.idea/"; - private static final Function<String, Boolean> PATH_FILTER = + private static final Function<String, Boolean> PATH_FILTER = SystemInfo.isFileSystemCaseSensitive? new Function<String, Boolean>() { @Override @@ -147,8 +157,55 @@ public class BuildManager implements ApplicationComponent{ private final SequentialTaskExecutor myRequestsProcessor = new SequentialTaskExecutor(myPooledThreadExecutor); private final Map<String, ProjectData> myProjectDataMap = Collections.synchronizedMap(new HashMap<String, ProjectData>()); - private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); - private final AtomicBoolean myAutoMakeInProgress = new AtomicBoolean(false); + private final BuildManagerPeriodicTask myAutoMakeTask = new BuildManagerPeriodicTask() { + @Override + protected int getDelay() { + return Registry.intValue("compiler.automake.trigger.delay", MAKE_TRIGGER_DELAY); + } + + @Override + protected void runTask() { + runAutoMake(); + } + }; + + private final BuildManagerPeriodicTask myDocumentSaveTask = new BuildManagerPeriodicTask() { + @Override + protected int getDelay() { + return Registry.intValue("compiler.document.save.trigger.delay", DOCUMENT_SAVE_TRIGGER_DELAY); + } + + private final Semaphore mySemaphore = new Semaphore(); + private final Runnable mySaveDocsRunnable = new Runnable() { + @Override + public void run() { + try { + FileDocumentManager.getInstance().saveAllDocuments(); + } + finally { + mySemaphore.up(); + } + } + }; + + @Override + public void runTask() { + if (shouldSaveDocuments()) { + mySemaphore.down(); + ApplicationManager.getApplication().invokeLater(mySaveDocsRunnable, ModalityState.NON_MODAL); + mySemaphore.waitFor(); + } + } + + private boolean shouldSaveDocuments() { + for (final Project project : getActiveProjects()) { + if (canStartAutoMake(project)) { + return true; + } + } + return false; + } + }; private final ChannelGroup myAllOpenChannels = new DefaultChannelGroup("build-manager"); private final BuildMessageDispatcher myMessageDispatcher = new BuildMessageDispatcher(); @@ -158,7 +215,8 @@ public class BuildManager implements ApplicationComponent{ private final Charset mySystemCharset; public BuildManager(final ProjectManager projectManager) { - IS_UNIT_TEST_MODE = ApplicationManager.getApplication().isUnitTestMode(); + final Application application = ApplicationManager.getApplication(); + IS_UNIT_TEST_MODE = application.isUnitTestMode(); myProjectManager = projectManager; mySystemCharset = CharsetToolkit.getDefaultSystemCharset(); final String systemPath = PathManager.getSystemPath(); @@ -172,8 +230,8 @@ public class BuildManager implements ApplicationComponent{ mySystemDirectory = system; projectManager.addProjectManagerListener(new ProjectWatcher()); - - final MessageBusConnection conn = ApplicationManager.getApplication().getMessageBus().connect(); + + final MessageBusConnection conn = application.getMessageBus().connect(); conn.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() { @Override public void after(@NotNull List<? extends VFileEvent> events) { @@ -192,16 +250,16 @@ public class BuildManager implements ApplicationComponent{ if (eventFile == null || ProjectCoreUtil.isProjectOrWorkspaceFile(eventFile)) { continue; } - + if (activeProjects == null) { activeProjects = getActiveProjects(); if (activeProjects.isEmpty()) { return false; } } - // todo: probably we do not need this excessive filtering + for (Project project : activeProjects) { - if (!project.isInitialized() || ProjectRootManager.getInstance(project).getFileIndex().isInContent(eventFile)) { + if (ProjectRootManager.getInstance(project).getFileIndex().isInContent(eventFile)) { return true; } } @@ -209,19 +267,12 @@ public class BuildManager implements ApplicationComponent{ return false; } - private List<Project> getActiveProjects() { - final Project[] projects = myProjectManager.getOpenProjects(); - if (projects.length == 0) { - return Collections.emptyList(); - } - final List<Project> projectList = new ArrayList<Project>(); - for (Project project : projects) { - if (project.isDefault() || project.isDisposed()) { - continue; - } - projectList.add(project); - } - return projectList; + }); + + EditorFactory.getInstance().getEventMulticaster().addDocumentListener(new DocumentAdapter() { + @Override + public void documentChanged(DocumentEvent e) { + scheduleProjectSave(); } }); @@ -233,6 +284,21 @@ public class BuildManager implements ApplicationComponent{ }); } + private List<Project> getActiveProjects() { + final Project[] projects = myProjectManager.getOpenProjects(); + if (projects.length == 0) { + return Collections.emptyList(); + } + final List<Project> projectList = new SmartList<Project>(); + for (Project project : projects) { + if (project.isDefault() || project.isDisposed() || !project.isInitialized()) { + continue; + } + projectList.add(project); + } + return projectList; + } + public static BuildManager getInstance() { return ApplicationManager.getApplication().getComponent(BuildManager.class); } @@ -345,97 +411,68 @@ public class BuildManager implements ApplicationComponent{ } public void scheduleAutoMake() { - if (IS_UNIT_TEST_MODE || PowerSaveMode.isEnabled()) { - return; + if (!IS_UNIT_TEST_MODE && !PowerSaveMode.isEnabled()) { + myAutoMakeTask.schedule(); } - addMakeRequest(new Runnable() { - @Override - public void run() { - if (!HeavyProcessLatch.INSTANCE.isRunning() && !myAutoMakeInProgress.getAndSet(true)) { - try { - ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { - @Override - public void run() { - try { - runAutoMake(); - } - finally { - myAutoMakeInProgress.set(false); - } - } - }); - } - catch (RejectedExecutionException ignored) { - // we were shut down - myAutoMakeInProgress.set(false); - } - catch (Throwable e) { - myAutoMakeInProgress.set(false); - throw new RuntimeException(e); - } - } - else { - addMakeRequest(this); - } - } - }); } - private void addMakeRequest(Runnable runnable) { - myAlarm.cancelAllRequests(); - final int delay = Math.max(50, Registry.intValue("compiler.automake.trigger.delay", MAKE_TRIGGER_DELAY)); - myAlarm.addRequest(runnable, delay); + private void scheduleProjectSave() { + if (!IS_UNIT_TEST_MODE && !PowerSaveMode.isEnabled()) { + myDocumentSaveTask.schedule(); + } } private void runAutoMake() { - final Project[] openProjects = myProjectManager.getOpenProjects(); - if (openProjects.length > 0) { - final List<RequestFuture> futures = new ArrayList<RequestFuture>(); - for (final Project project : openProjects) { - if (project.isDefault() || project.isDisposed()) { - continue; - } - final CompilerWorkspaceConfiguration config = CompilerWorkspaceConfiguration.getInstance(project); - if (!config.useOutOfProcessBuild() || !config.MAKE_PROJECT_ON_SAVE) { - continue; - } - if (!config.allowAutoMakeWhileRunningApplication()) { - final RunContentManager contentManager = ExecutionManager.getInstance(project).getContentManager(); - boolean hasRunningProcesses = false; - for (RunContentDescriptor descriptor : contentManager.getAllDescriptors()) { - final ProcessHandler handler = descriptor.getProcessHandler(); - if (handler != null && !handler.isProcessTerminated()) { // active process - hasRunningProcesses = true; - break; - } - } - if (hasRunningProcesses) { - continue; - } - } - - final List<String> emptyList = Collections.emptyList(); - final RequestFuture future = scheduleBuild( - project, false, true, false, CmdlineProtoUtil.createAllModulesScopes(), emptyList, Collections.<String, String>emptyMap(), new AutoMakeMessageHandler(project) - ); - if (future != null) { - futures.add(future); - synchronized (myAutomakeFutures) { - myAutomakeFutures.put(future, project); - } - } - } - try { - for (RequestFuture future : futures) { - future.waitFor(); - } + final List<RequestFuture> futures = new ArrayList<RequestFuture>(); + for (final Project project : getActiveProjects()) { + if (!canStartAutoMake(project)) { + continue; } - finally { + final List<String> emptyList = Collections.emptyList(); + final RequestFuture future = scheduleBuild( + project, false, true, false, CmdlineProtoUtil.createAllModulesScopes(), emptyList, Collections.<String, String>emptyMap(), new AutoMakeMessageHandler(project) + ); + if (future != null) { + futures.add(future); synchronized (myAutomakeFutures) { - myAutomakeFutures.keySet().removeAll(futures); + myAutomakeFutures.put(future, project); } } } + try { + for (RequestFuture future : futures) { + future.waitFor(); + } + } + finally { + synchronized (myAutomakeFutures) { + myAutomakeFutures.keySet().removeAll(futures); + } + } + } + + private static boolean canStartAutoMake(Project project) { + if (project.isDisposed()) { + return false; + } + final CompilerWorkspaceConfiguration config = CompilerWorkspaceConfiguration.getInstance(project); + if (!config.useOutOfProcessBuild() || !config.MAKE_PROJECT_ON_SAVE) { + return false; + } + if (!config.allowAutoMakeWhileRunningApplication() && hasRunningProcess(project)) { + return false; + } + return true; + } + + private static boolean hasRunningProcess(Project project) { + for (RunContentDescriptor descriptor : ExecutionManager.getInstance(project).getContentManager().getAllDescriptors()) { + final ProcessHandler handler = descriptor.getProcessHandler(); + if (handler != null && !handler.isProcessTerminated() && !ALLOW_AUTOMAKE.get(handler, Boolean.FALSE)) { // active process + return true; + } + } + return false; } public Collection<RequestFuture> cancelAutoMakeTasks(Project project) { @@ -553,7 +590,7 @@ public class BuildManager implements ApplicationComponent{ projectTaskQueue.submit(new Runnable() { @Override public void run() { - ExecutionException execFailure = null; + Throwable execFailure = null; try { if (project.isDisposed()) { return; @@ -594,7 +631,7 @@ public class BuildManager implements ApplicationComponent{ handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure("Disconnected from build process", null)); } } - catch (ExecutionException e) { + catch (Throwable e) { execFailure = e; } finally { @@ -683,66 +720,83 @@ public class BuildManager implements ApplicationComponent{ } private OSProcessHandler launchBuildProcess(Project project, final int port, final UUID sessionId) throws ExecutionException { - // choosing sdk with which the build process should be run - Sdk projectJdk = null; + final String compilerPath; + final String vmExecutablePath; JavaSdkVersion sdkVersion = null; - int sdkMinorVersion = 0; - final Set<Sdk> candidates = new HashSet<Sdk>(); - for (Module module : ModuleManager.getInstance(project).getModules()) { - final Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); - if (sdk != null && sdk.getSdkType() instanceof JavaSdk) { - candidates.add(sdk); + final String forcedCompiledJdkHome = Registry.stringValue(COMPILER_PROCESS_JDK_PROPERTY); + + if (StringUtil.isEmptyOrSpaces(forcedCompiledJdkHome)) { + // choosing sdk with which the build process should be run + Sdk projectJdk = null; + int sdkMinorVersion = 0; + + final Set<Sdk> candidates = new HashSet<Sdk>(); + final Sdk defaultSdk = ProjectRootManager.getInstance(project).getProjectSdk(); + if (defaultSdk != null && defaultSdk.getSdkType() instanceof JavaSdk) { + candidates.add(defaultSdk); } - } - // now select the latest version from the sdks that are used in the project, but not older than the internal sdk version - for (Sdk candidate : candidates) { - final String vs = candidate.getVersionString(); - if (vs != null) { - final JavaSdkVersion candidateVersion = ((JavaSdk)candidate.getSdkType()).getVersion(vs); - if (candidateVersion != null) { - final int candidateMinorVersion = getMinorVersion(vs); - if (projectJdk == null) { - sdkVersion = candidateVersion; - sdkMinorVersion = candidateMinorVersion; - projectJdk = candidate; - } - else { - final int result = candidateVersion.compareTo(sdkVersion); - if (result > 0 || (result == 0 && candidateMinorVersion > sdkMinorVersion)) { + + for (Module module : ModuleManager.getInstance(project).getModules()) { + final Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); + if (sdk != null && sdk.getSdkType() instanceof JavaSdk) { + candidates.add(sdk); + } + } + + // now select the latest version from the sdks that are used in the project, but not older than the internal sdk version + for (Sdk candidate : candidates) { + final String vs = candidate.getVersionString(); + if (vs != null) { + final JavaSdkVersion candidateVersion = ((JavaSdk)candidate.getSdkType()).getVersion(vs); + if (candidateVersion != null) { + final int candidateMinorVersion = getMinorVersion(vs); + if (projectJdk == null) { sdkVersion = candidateVersion; sdkMinorVersion = candidateMinorVersion; projectJdk = candidate; } + else { + final int result = candidateVersion.compareTo(sdkVersion); + if (result > 0 || (result == 0 && candidateMinorVersion > sdkMinorVersion)) { + sdkVersion = candidateVersion; + sdkMinorVersion = candidateMinorVersion; + projectJdk = candidate; + } + } } } } - } - final Sdk internalJdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk(); - if (projectJdk == null || sdkVersion == null || !sdkVersion.isAtLeast(JavaSdkVersion.JDK_1_6)) { - projectJdk = internalJdk; - } + final Sdk internalJdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk(); + if (projectJdk == null || sdkVersion == null || !sdkVersion.isAtLeast(JavaSdkVersion.JDK_1_6)) { + projectJdk = internalJdk; + } - // validate tools.jar presence - final String compilerPath; - if (projectJdk.equals(internalJdk)) { - final JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler(); - if (systemCompiler == null) { - throw new ExecutionException("No system java compiler is provided by the JRE. Make sure tools.jar is present in IntelliJ IDEA classpath."); + // validate tools.jar presence + if (projectJdk.equals(internalJdk)) { + final JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler(); + if (systemCompiler == null) { + throw new ExecutionException("No system java compiler is provided by the JRE. Make sure tools.jar is present in IntelliJ IDEA classpath."); + } + compilerPath = ClasspathBootstrap.getResourcePath(systemCompiler.getClass()); } - compilerPath = ClasspathBootstrap.getResourcePath(systemCompiler.getClass()); + else { + compilerPath = ((JavaSdk)projectJdk.getSdkType()).getToolsPath(projectJdk); + if (compilerPath == null) { + throw new ExecutionException("Cannot determine path to 'tools.jar' library for " + projectJdk.getName() + " (" + projectJdk.getHomePath() + ")"); + } + } + + vmExecutablePath = ((JavaSdkType)projectJdk.getSdkType()).getVMExecutablePath(projectJdk); } else { - compilerPath = ((JavaSdk)projectJdk.getSdkType()).getToolsPath(projectJdk); - if (compilerPath == null) { - throw new ExecutionException("Cannot determine path to 'tools.jar' library for " + projectJdk.getName() + " (" + projectJdk.getHomePath() + ")"); - } + compilerPath = new File(forcedCompiledJdkHome, "lib/tools.jar").getAbsolutePath(); + vmExecutablePath = new File(forcedCompiledJdkHome, "bin/java").getAbsolutePath(); } final CompilerWorkspaceConfiguration config = CompilerWorkspaceConfiguration.getInstance(project); final GeneralCommandLine cmdLine = new GeneralCommandLine(); - final String vmExecutablePath = ((JavaSdkType)projectJdk.getSdkType()).getVMExecutablePath(projectJdk); cmdLine.setExePath(vmExecutablePath); //cmdLine.addParameter("-XX:MaxPermSize=150m"); //cmdLine.addParameter("-XX:ReservedCodeCacheSize=64m"); @@ -805,6 +859,7 @@ public class BuildManager implements ApplicationComponent{ cmdLine.setCharset(mySystemCharset); cmdLine.addParameter("-D" + CharsetToolkit.FILE_ENCODING_PROPERTY + "=" + mySystemCharset.name()); } + cmdLine.addParameter("-D" + JpsGlobalLoader.FILE_TYPES_COMPONENT_NAME_KEY + "=" + FileTypeManagerImpl.getFileTypeComponentName()); for (String name : new String[]{"user.language", "user.country", "user.region", PathManager.PROPERTY_HOME_PATH}) { final String value = System.getProperty(name); if (value != null) { @@ -816,6 +871,8 @@ public class BuildManager implements ApplicationComponent{ workDirectory.mkdirs(); ensureLogConfigExists(workDirectory); + cmdLine.addParameter("-Djava.io.tmpdir=" + FileUtil.toSystemIndependentName(workDirectory.getPath()) + "/_temp_"); + final List<String> cp = ClasspathBootstrap.getBuildProcessApplicationClasspath(); cp.add(compilerPath); cp.addAll(myClasspathManager.getCompileServerPluginsClasspath(project)); @@ -992,6 +1049,52 @@ public class BuildManager implements ApplicationComponent{ } } + private static abstract class BuildManagerPeriodicTask implements Runnable { + private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + private final AtomicBoolean myInProgress = new AtomicBoolean(false); + private final Runnable myTaskRunnable = new Runnable() { + @Override + public void run() { + try { + runTask(); + } + finally { + myInProgress.set(false); + } + } + }; + + public final void schedule() { + myAlarm.cancelAllRequests(); + final int delay = Math.max(100, getDelay()); + myAlarm.addRequest(this, delay); + } + + protected abstract int getDelay(); + + protected abstract void runTask(); + + @Override + public final void run() { + if (!HeavyProcessLatch.INSTANCE.isRunning() && !myInProgress.getAndSet(true)) { + try { + ApplicationManager.getApplication().executeOnPooledThread(myTaskRunnable); + } + catch (RejectedExecutionException ignored) { + // we were shut down + myInProgress.set(false); + } + catch (Throwable e) { + myInProgress.set(false); + throw new RuntimeException(e); + } + } + else { + schedule(); + } + } + } + private class ProjectWatcher extends ProjectManagerAdapter { private final Map<Project, MessageBusConnection> myConnections = new HashMap<Project, MessageBusConnection>(); @@ -1021,7 +1124,12 @@ public class BuildManager implements ApplicationComponent{ myProjectDataMap.remove(projectPath); } }); - scheduleAutoMake(); // run automake on project opening + StartupManager.getInstance(project).registerPostStartupActivity(new Runnable() { + @Override + public void run() { + scheduleAutoMake(); // run automake after project opened + } + }); } @Override diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java index a1fa1b427159..2154a095007e 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -145,7 +145,7 @@ public class BuildArtifactsBeforeRunTaskProvider extends BeforeRunTaskProvider<B builder.addOkAction(); builder.addCancelAction(); builder.setCenterPanel(chooser); - builder.setPreferedFocusComponent(chooser); + builder.setPreferredFocusComponent(chooser); if (builder.show() == DialogWrapper.OK_EXIT_CODE) { task.setArtifactPointers(chooser.getMarkedElements()); return true; diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileWorker.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileWorker.java index 6be07f023bb7..66f0be6d61e6 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileWorker.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileWorker.java @@ -30,6 +30,7 @@ import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Trinity; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -159,7 +160,8 @@ public class PackageFileWorker { try { final JBZipEntry entry = zipFile.getOrCreateEntry(nextPathInArchive); LOG.debug(" extracting to temp file: " + nextPathInArchive + " from " + archivePath); - final File tempFile = FileUtil.createTempFile("packageFile" + FileUtil.sanitizeFileName(nextPathInArchive), FileUtil.getExtension(PathUtil.getFileName(nextPathInArchive))); + final File tempFile = FileUtil.createTempFile("packageFile" + FileUtil.sanitizeFileName(nextPathInArchive), + FileUtilRt.getExtension(PathUtil.getFileName(nextPathInArchive))); if (entry.getSize() != -1) { FileUtil.writeToFile(tempFile, entry.getData()); } diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java index ebd49e47939f..8f7528371457 100644 --- a/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java +++ b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java @@ -1,7 +1,9 @@ package com.intellij.compiler; +import com.intellij.ProjectTopics; import com.intellij.compiler.impl.CompileDriver; import com.intellij.compiler.impl.ExitStatus; +import com.intellij.compiler.server.BuildManager; import com.intellij.ide.highlighter.ModuleFileType; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; @@ -11,9 +13,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl; -import com.intellij.openapi.roots.CompilerModuleExtension; -import com.intellij.openapi.roots.CompilerProjectExtension; -import com.intellij.openapi.roots.ModuleRootModificationUtil; +import com.intellij.openapi.roots.*; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; @@ -60,6 +60,13 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { protected void setUp() throws Exception { super.setUp(); if (useExternalCompiler()) { + myProject.getMessageBus().connect(myTestRootDisposable).subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() { + @Override + public void rootsChanged(ModuleRootEvent event) { + //todo[nik] projectOpened isn't called in tests so we need to add this listener manually + forceFSRescan(); + } + }); CompilerTestUtil.enableExternalCompiler(myProject); } else { @@ -67,6 +74,10 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { } } + protected void forceFSRescan() { + BuildManager.getInstance().clearState(myProject); + } + @Override protected Sdk getTestProjectJdk() { if (useExternalCompiler()) { @@ -249,7 +260,7 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { }; if (useExternalCompiler()) { myProject.save(); - CompilerTestUtil.saveSdkTable(); + CompilerTestUtil.saveApplicationSettings(); CompilerTestUtil.scanSourceRootsToRecompile(myProject); } action.run(callback); diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/CompilerTestUtil.java b/java/compiler/impl/testSrc/com/intellij/compiler/CompilerTestUtil.java index 69cb63ab8e55..a2d50b39048b 100644 --- a/java/compiler/impl/testSrc/com/intellij/compiler/CompilerTestUtil.java +++ b/java/compiler/impl/testSrc/com/intellij/compiler/CompilerTestUtil.java @@ -3,15 +3,19 @@ package com.intellij.compiler; import com.intellij.compiler.impl.TranslatingCompilerFilesMonitor; import com.intellij.compiler.impl.javaCompiler.javac.JavacConfiguration; import com.intellij.compiler.server.BuildManager; +import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl; import com.intellij.openapi.projectRoots.impl.ProjectJdkTableImpl; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.SystemProperties; @@ -48,18 +52,29 @@ public class CompilerTestUtil { TranslatingCompilerFilesMonitor.getInstance().scanSourceContent(new TranslatingCompilerFilesMonitor.ProjectRef(project), roots, roots.size(), true); } - public static void saveSdkTable() { + public static void saveApplicationSettings() { try { ProjectJdkTableImpl table = (ProjectJdkTableImpl)ProjectJdkTable.getInstance(); - File sdkFile = table.getExportFiles()[0]; - FileUtil.createParentDirs(sdkFile); Element root = new Element("application"); root.addContent(JDomSerializationUtil.createComponentElement(JpsGlobalLoader.SDK_TABLE_COMPONENT_NAME).addContent(table.getState().cloneContent())); - JDOMUtil.writeDocument(new Document(root), sdkFile, SystemProperties.getLineSeparator()); + saveApplicationComponent(root, ((ProjectJdkTableImpl)ProjectJdkTable.getInstance()).getExportFiles()[0]); + + FileTypeManagerImpl fileTypeManager = (FileTypeManagerImpl)FileTypeManager.getInstance(); + Element fileTypesComponent = JDomSerializationUtil.createComponentElement(fileTypeManager.getComponentName()); + fileTypeManager.writeExternal(fileTypesComponent); + saveApplicationComponent(new Element("application").addContent(fileTypesComponent), PathManager.getOptionsFile(fileTypeManager)); } catch (IOException e) { throw new RuntimeException(e); } + catch (WriteExternalException e) { + throw new RuntimeException(e); + } + } + + private static void saveApplicationComponent(Element root, final File file) throws IOException { + FileUtil.createParentDirs(file); + JDOMUtil.writeDocument(new Document(root), file, SystemProperties.getLineSeparator()); } public static void enableExternalCompiler(final Project project) { diff --git a/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumentationClassFinder.java b/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumentationClassFinder.java index abde877bb04e..53f993670050 100644 --- a/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumentationClassFinder.java +++ b/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumentationClassFinder.java @@ -97,14 +97,23 @@ public class InstrumentationClassFinder { public PseudoClass loadClass(final String name) throws IOException, ClassNotFoundException{ final String internalName = name.replace('.', '/'); // normalize final PseudoClass aClass = myLoaded.get(internalName); - if (aClass != null) { + if (aClass != null && aClass != PseudoClass.NULL_OBJ) { return aClass; } - final InputStream is = getClassBytesAsStream(internalName); + final InputStream is = aClass == null? getClassBytesAsStream(internalName) : null; if (is == null) { - throw new ClassNotFoundException("Class not found: " + name.replace('/', '.')); // ensure presentable class name in error message + if (aClass == null) { + myLoaded.put(internalName, PseudoClass.NULL_OBJ); + } + // ensure presentable class name in error message + throw new ClassNotFoundException("Class not found: " + name.replace('/', '.')) { + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } + }; } try { @@ -128,7 +137,7 @@ public class InstrumentationClassFinder { final String resourceName = internalName + CLASS_RESOURCE_EXTENSION; Resource resource = myPlatformClasspath.getResource(resourceName, false); if (resource != null) { - is = resource.getInputStream(); + is = new ByteArrayInputStream(resource.getBytes()); } // second look into memory and classspath if (is == null) { @@ -138,7 +147,7 @@ public class InstrumentationClassFinder { if (is == null) { resource = myClasspath.getResource(resourceName, false); if (resource != null) { - is = resource.getInputStream(); + is = new ByteArrayInputStream(resource.getBytes()); } } @@ -153,13 +162,13 @@ public class InstrumentationClassFinder { Resource resource = myPlatformClasspath.getResource(resourceName, false); if (resource != null) { - is = resource.getInputStream(); + is = new ByteArrayInputStream(resource.getBytes()); } if (is == null) { resource = myClasspath.getResource(resourceName, false); if (resource != null) { - is = resource.getInputStream(); + is = new ByteArrayInputStream(resource.getBytes()); } } @@ -180,22 +189,30 @@ public class InstrumentationClassFinder { reader.accept(visitor, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); - return new PseudoClass(visitor.myName, visitor.mySuperclassName, visitor.myInterfaces, visitor.myModifiers, visitor.myMethods); + return new PseudoClass(this, visitor.myName, visitor.mySuperclassName, visitor.myInterfaces, visitor.myModifiers, visitor.myMethods); } - public final class PseudoClass { + public static class PseudoClass { + static final PseudoClass NULL_OBJ = new PseudoClass(null, null, null, null, 0, null); private final String myName; private final String mySuperClass; private final String[] myInterfaces; private final int myModifiers; private final List<PseudoMethod> myMethods; - - private PseudoClass(final String name, final String superClass, final String[] interfaces, final int modifiers, List<PseudoMethod> methods) { + private final InstrumentationClassFinder myFinder; + + private PseudoClass(InstrumentationClassFinder finder, + final String name, + final String superClass, + final String[] interfaces, + final int modifiers, + List<PseudoMethod> methods) { myName = name; mySuperClass = superClass; myInterfaces = interfaces; myModifiers = modifiers; myMethods = methods; + myFinder = finder; } public int getModifiers() { @@ -234,12 +251,12 @@ public class InstrumentationClassFinder { } public InstrumentationClassFinder getFinder() { - return InstrumentationClassFinder.this; + return myFinder; } public PseudoClass getSuperClass() throws IOException, ClassNotFoundException { final String superClass = mySuperClass; - return superClass != null? loadClass(superClass) : null; + return superClass != null? myFinder.loadClass(superClass) : null; } public PseudoClass[] getInterfaces() throws IOException, ClassNotFoundException { @@ -250,7 +267,7 @@ public class InstrumentationClassFinder { final PseudoClass[] result = new PseudoClass[myInterfaces.length]; for (int i = 0; i < result.length; i++) { - result[i] = loadClass(myInterfaces[i]); + result[i] = myFinder.loadClass(myInterfaces[i]); } return result; diff --git a/java/compiler/javac2/src/com/intellij/ant/Javac2.java b/java/compiler/javac2/src/com/intellij/ant/Javac2.java index 36762616a85d..17dab63e48dc 100644 --- a/java/compiler/javac2/src/com/intellij/ant/Javac2.java +++ b/java/compiler/javac2/src/com/intellij/ant/Javac2.java @@ -36,455 +36,468 @@ import java.net.URL; import java.util.*; public class Javac2 extends Javac { - private ArrayList myFormFiles; - private List myNestedFormPathList; + public static final String PROPERTY_INSTRUMENTATION_INCLUDE_JAVA_RUNTIME = "javac2.instrumentation.includeJavaRuntime"; + private ArrayList myFormFiles; + private List myNestedFormPathList; - public Javac2() { - } + public Javac2() { + } - /** - * Check if Java classes should be actually compiled by the task. This method is overridden by - * {@link com.intellij.ant.InstrumentIdeaExtensions} task in order to suppress actual compilation - * of the java sources. - * - * @return true if the java classes are compiled, false if just instrumentation is performed. - */ - protected boolean areJavaClassesCompiled() { - return true; - } + /** + * Check if Java classes should be actually compiled by the task. This method is overridden by + * {@link com.intellij.ant.InstrumentIdeaExtensions} task in order to suppress actual compilation + * of the java sources. + * + * @return true if the java classes are compiled, false if just instrumentation is performed. + */ + protected boolean areJavaClassesCompiled() { + return true; + } - /** - * This method is called when option that supported only for the case when java sources are compiled - * and it is not supported for the case when only instrumentation is performed. - * - * @param optionName the option name to warn about. - */ - private void unsupportedOptionMessage(final String optionName) { - if (!areJavaClassesCompiled()) { - log("The option " + optionName + " is not supported by InstrumentIdeaExtensions task", Project.MSG_ERR); - } + /** + * This method is called when option that supported only for the case when java sources are compiled + * and it is not supported for the case when only instrumentation is performed. + * + * @param optionName the option name to warn about. + */ + private void unsupportedOptionMessage(final String optionName) { + if (!areJavaClassesCompiled()) { + log("The option " + optionName + " is not supported by InstrumentIdeaExtensions task", Project.MSG_ERR); } + } - /** - * The overridden setter method that warns about unsupported option. - * - * @param v the option value - */ - public void setDebugLevel(String v) { - unsupportedOptionMessage("debugLevel"); - super.setDebugLevel(v); - } + /** + * The overridden setter method that warns about unsupported option. + * + * @param v the option value + */ + public void setDebugLevel(String v) { + unsupportedOptionMessage("debugLevel"); + super.setDebugLevel(v); + } - /** - * The overridden setter method that warns about unsupported option. - * - * @param list the option value - */ - public void setListfiles(boolean list) { - unsupportedOptionMessage("listFiles"); - super.setListfiles(list); - } + /** + * The overridden setter method that warns about unsupported option. + * + * @param list the option value + */ + public void setListfiles(boolean list) { + unsupportedOptionMessage("listFiles"); + super.setListfiles(list); + } - /** - * The overridden setter method that warns about unsupported option. - * - * @param memoryInitialSize the option value - */ - public void setMemoryInitialSize(String memoryInitialSize) { - unsupportedOptionMessage("memoryInitialSize"); - super.setMemoryInitialSize(memoryInitialSize); - } + /** + * The overridden setter method that warns about unsupported option. + * + * @param memoryInitialSize the option value + */ + public void setMemoryInitialSize(String memoryInitialSize) { + unsupportedOptionMessage("memoryInitialSize"); + super.setMemoryInitialSize(memoryInitialSize); + } - /** - * The overridden setter method that warns about unsupported option. - * - * @param memoryMaximumSize the option value - */ - public void setMemoryMaximumSize(String memoryMaximumSize) { - unsupportedOptionMessage("memoryMaximumSize"); - super.setMemoryMaximumSize(memoryMaximumSize); - } + /** + * The overridden setter method that warns about unsupported option. + * + * @param memoryMaximumSize the option value + */ + public void setMemoryMaximumSize(String memoryMaximumSize) { + unsupportedOptionMessage("memoryMaximumSize"); + super.setMemoryMaximumSize(memoryMaximumSize); + } - /** - * The overridden setter method that warns about unsupported option. - * - * @param encoding the option value - */ - public void setEncoding(String encoding) { - unsupportedOptionMessage("encoding"); - super.setEncoding(encoding); - } + /** + * The overridden setter method that warns about unsupported option. + * + * @param encoding the option value + */ + public void setEncoding(String encoding) { + unsupportedOptionMessage("encoding"); + super.setEncoding(encoding); + } - /** - * The overridden setter method that warns about unsupported option. - * - * @param optimize the option value - */ - public void setOptimize(boolean optimize) { - unsupportedOptionMessage("optimize"); - super.setOptimize(optimize); - } + /** + * The overridden setter method that warns about unsupported option. + * + * @param optimize the option value + */ + public void setOptimize(boolean optimize) { + unsupportedOptionMessage("optimize"); + super.setOptimize(optimize); + } - /** - * The overridden setter method that warns about unsupported option. - * - * @param depend the option value - */ - public void setDepend(boolean depend) { - unsupportedOptionMessage("depend"); - super.setDepend(depend); - } + /** + * The overridden setter method that warns about unsupported option. + * + * @param depend the option value + */ + public void setDepend(boolean depend) { + unsupportedOptionMessage("depend"); + super.setDepend(depend); + } - /** - * The overridden setter method that warns about unsupported option. - * - * @param f the option value - */ - public void setFork(boolean f) { - unsupportedOptionMessage("fork"); - super.setFork(f); - } + /** + * The overridden setter method that warns about unsupported option. + * + * @param f the option value + */ + public void setFork(boolean f) { + unsupportedOptionMessage("fork"); + super.setFork(f); + } - /** - * The overridden setter method that warns about unsupported option. - * - * @param forkExec the option value - */ - public void setExecutable(String forkExec) { - unsupportedOptionMessage("executable"); - super.setExecutable(forkExec); - } + /** + * The overridden setter method that warns about unsupported option. + * + * @param forkExec the option value + */ + public void setExecutable(String forkExec) { + unsupportedOptionMessage("executable"); + super.setExecutable(forkExec); + } - /** - * The overridden setter method that warns about unsupported option. - * - * @param compiler the option value - */ - public void setCompiler(String compiler) { - unsupportedOptionMessage("compiler"); - super.setCompiler(compiler); - } + /** + * The overridden setter method that warns about unsupported option. + * + * @param compiler the option value + */ + public void setCompiler(String compiler) { + unsupportedOptionMessage("compiler"); + super.setCompiler(compiler); + } - /** - * Sets the nested form directories that will be used during the - * compilation. - * @param nestedformdirs a list of {@link PrefixedPath} - */ - public void setNestedformdirs(List nestedformdirs) { - myNestedFormPathList = nestedformdirs; - } + /** + * Sets the nested form directories that will be used during the + * compilation. + * @param nestedformdirs a list of {@link PrefixedPath} + */ + public void setNestedformdirs(List nestedformdirs) { + myNestedFormPathList = nestedformdirs; + } - /** - * Gets the nested form directories that will be used during the - * compilation. - * @return the extension directories as a list of {@link PrefixedPath} - */ - public List getNestedformdirs() { - return myNestedFormPathList; - } + /** + * Gets the nested form directories that will be used during the + * compilation. + * @return the extension directories as a list of {@link PrefixedPath} + */ + public List getNestedformdirs() { + return myNestedFormPathList; + } - /** - * Adds a path to nested form directories. - * @return a path to be configured - */ - public PrefixedPath createNestedformdirs() { - PrefixedPath p = new PrefixedPath(getProject()); - if (myNestedFormPathList == null) { - myNestedFormPathList = new ArrayList(); - } - myNestedFormPathList.add(p); - return p; + /** + * Adds a path to nested form directories. + * @return a path to be configured + */ + public PrefixedPath createNestedformdirs() { + PrefixedPath p = new PrefixedPath(getProject()); + if (myNestedFormPathList == null) { + myNestedFormPathList = new ArrayList(); } + myNestedFormPathList.add(p); + return p; + } - /** - * The overridden compile method that does not actually compiles java sources but only instruments - * class files. - */ - protected void compile() { - // compile java - if (areJavaClassesCompiled()) { - super.compile(); - } + /** + * The overridden compile method that does not actually compiles java sources but only instruments + * class files. + */ + protected void compile() { + // compile java + if (areJavaClassesCompiled()) { + super.compile(); + } - InstrumentationClassFinder finder = buildClasspathClassLoader(); - if (finder == null) { - return; - } - try { - instrumentForms(finder); + InstrumentationClassFinder finder = buildClasspathClassLoader(); + if (finder == null) { + return; + } + try { + instrumentForms(finder); - //NotNull instrumentation - final int instrumented = instrumentNotNull(getDestdir(), finder); + //NotNull instrumentation + final int instrumented = instrumentNotNull(getDestdir(), finder); - log("Added @NotNull assertions to " + instrumented + " files", Project.MSG_INFO); - } - finally { - finder.releaseResources(); - } + log("Added @NotNull assertions to " + instrumented + " files", Project.MSG_INFO); } + finally { + finder.releaseResources(); + } + } /** - * Instrument forms - * - * @param finder a classloader to use - */ - private void instrumentForms(final InstrumentationClassFinder finder) { - // we instrument every file, because we cannot find which files should not be instrumented without dependency storage - final ArrayList formsToInstrument = myFormFiles; - - if (formsToInstrument.size() == 0) { - log("No forms to instrument found", Project.MSG_VERBOSE); - return; - } + * Instrument forms + * + * @param finder a classloader to use + */ + private void instrumentForms(final InstrumentationClassFinder finder) { + // we instrument every file, because we cannot find which files should not be instrumented without dependency storage + final ArrayList formsToInstrument = myFormFiles; + + if (formsToInstrument.size() == 0) { + log("No forms to instrument found", Project.MSG_VERBOSE); + return; + } - final HashMap class2form = new HashMap(); + final HashMap class2form = new HashMap(); - for (int i = 0; i < formsToInstrument.size(); i++) { - final File formFile = (File)formsToInstrument.get(i); + for (int i = 0; i < formsToInstrument.size(); i++) { + final File formFile = (File)formsToInstrument.get(i); - log("compiling form " + formFile.getAbsolutePath(), Project.MSG_VERBOSE); - final LwRootContainer rootContainer; - try { - rootContainer = Utils.getRootContainer(formFile.toURI().toURL(), new CompiledClassPropertiesProvider(finder.getLoader())); - } - catch (AlienFormFileException e) { - // ignore non-IDEA forms - continue; - } - catch (Exception e) { - fireError("Cannot process form file " + formFile.getAbsolutePath() + ". Reason: " + e); - continue; - } + log("compiling form " + formFile.getAbsolutePath(), Project.MSG_VERBOSE); + final LwRootContainer rootContainer; + try { + rootContainer = Utils.getRootContainer(formFile.toURI().toURL(), new CompiledClassPropertiesProvider(finder.getLoader())); + } + catch (AlienFormFileException e) { + // ignore non-IDEA forms + continue; + } + catch (Exception e) { + fireError("Cannot process form file " + formFile.getAbsolutePath() + ". Reason: " + e); + continue; + } - final String classToBind = rootContainer.getClassToBind(); - if (classToBind == null) { - continue; - } + final String classToBind = rootContainer.getClassToBind(); + if (classToBind == null) { + continue; + } - String name = classToBind.replace('.', '/'); - File classFile = getClassFile(name); - if (classFile == null) { - log(formFile.getAbsolutePath() + ": Class to bind does not exist: " + classToBind, Project.MSG_WARN); - continue; - } + String name = classToBind.replace('.', '/'); + File classFile = getClassFile(name); + if (classFile == null) { + log(formFile.getAbsolutePath() + ": Class to bind does not exist: " + classToBind, Project.MSG_WARN); + continue; + } - final File alreadyProcessedForm = (File)class2form.get(classToBind); - if (alreadyProcessedForm != null) { - fireError(formFile.getAbsolutePath() + - ": " + - "The form is bound to the class " + - classToBind + - ".\n" + - "Another form " + - alreadyProcessedForm.getAbsolutePath() + - " is also bound to this class."); - continue; - } - class2form.put(classToBind, formFile); + final File alreadyProcessedForm = (File)class2form.get(classToBind); + if (alreadyProcessedForm != null) { + fireError(formFile.getAbsolutePath() + + ": " + + "The form is bound to the class " + + classToBind + + ".\n" + + "Another form " + + alreadyProcessedForm.getAbsolutePath() + + " is also bound to this class."); + continue; + } + class2form.put(classToBind, formFile); - try { - int version; - InputStream stream = new FileInputStream(classFile); - try { - version = getClassFileVersion(new ClassReader(stream)); - } - finally { - stream.close(); - } - AntNestedFormLoader formLoader = new AntNestedFormLoader(finder.getLoader(), myNestedFormPathList); - InstrumenterClassWriter classWriter = new InstrumenterClassWriter(getAsmClassWriterFlags(version), finder); - final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, finder, formLoader, false, classWriter); - codeGenerator.patchFile(classFile); - final FormErrorInfo[] warnings = codeGenerator.getWarnings(); - - for (int j = 0; j < warnings.length; j++) { - log(formFile.getAbsolutePath() + ": " + warnings[j].getErrorMessage(), Project.MSG_WARN); - } - final FormErrorInfo[] errors = codeGenerator.getErrors(); - if (errors.length > 0) { - StringBuffer message = new StringBuffer(); - for (int j = 0; j < errors.length; j++) { - if (message.length() > 0) { - message.append("\n"); - } - message.append(formFile.getAbsolutePath()).append(": ").append(errors[j].getErrorMessage()); - } - fireError(message.toString()); - } - } - catch (Exception e) { - fireError("Forms instrumentation failed for " + formFile.getAbsolutePath() + ": " + e.toString()); + try { + int version; + InputStream stream = new FileInputStream(classFile); + try { + version = getClassFileVersion(new ClassReader(stream)); + } + finally { + stream.close(); + } + AntNestedFormLoader formLoader = new AntNestedFormLoader(finder.getLoader(), myNestedFormPathList); + InstrumenterClassWriter classWriter = new InstrumenterClassWriter(getAsmClassWriterFlags(version), finder); + final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, finder, formLoader, false, classWriter); + codeGenerator.patchFile(classFile); + final FormErrorInfo[] warnings = codeGenerator.getWarnings(); + + for (int j = 0; j < warnings.length; j++) { + log(formFile.getAbsolutePath() + ": " + warnings[j].getErrorMessage(), Project.MSG_WARN); + } + final FormErrorInfo[] errors = codeGenerator.getErrors(); + if (errors.length > 0) { + StringBuffer message = new StringBuffer(); + for (int j = 0; j < errors.length; j++) { + if (message.length() > 0) { + message.append("\n"); } + message.append(formFile.getAbsolutePath()).append(": ").append(errors[j].getErrorMessage()); + } + fireError(message.toString()); } + } + catch (Exception e) { + fireError("Forms instrumentation failed for " + formFile.getAbsolutePath() + ": " + e.toString()); + } } + } + + /** + * @return the flags for class writer + */ + private static int getAsmClassWriterFlags(int version) { + return version >= Opcodes.V1_6 && version != Opcodes.V1_1 ? ClassWriter.COMPUTE_FRAMES : ClassWriter.COMPUTE_MAXS; + } - /** - * @return the flags for class writer - */ - private static int getAsmClassWriterFlags(int version) { - return version >= Opcodes.V1_6 && version != Opcodes.V1_1 ? ClassWriter.COMPUTE_FRAMES : ClassWriter.COMPUTE_MAXS; + /** + * Create class loader based on classpath, bootclasspath, and sourcepath. + * + * @return a URL classloader + */ + private InstrumentationClassFinder buildClasspathClassLoader() { + final StringBuffer classPathBuffer = new StringBuffer(); + final Project project = getProject(); + final Path cp = new Path(project); + appendPath(cp, getBootclasspath()); + cp.setLocation(getDestdir().getAbsoluteFile()); + appendPath(cp, getClasspath()); + appendPath(cp, getSourcepath()); + appendPath(cp, getSrcdir()); + if (getIncludeantruntime()) { + cp.addExisting(cp.concatSystemClasspath("last")); + } + boolean shouldInclude = getIncludejavaruntime(); + if (!shouldInclude) { + if (project != null) { + final String propValue = project.getProperty(PROPERTY_INSTRUMENTATION_INCLUDE_JAVA_RUNTIME); + shouldInclude = !("false".equalsIgnoreCase(propValue) || "no".equalsIgnoreCase(propValue)); + } + else { + shouldInclude = true; + } + } + if (shouldInclude) { + cp.addJavaRuntime(); } - /** - * Create class loader based on classpath, bootclasspath, and sourcepath. - * - * @return a URL classloader - */ - private InstrumentationClassFinder buildClasspathClassLoader() { - final StringBuffer classPathBuffer = new StringBuffer(); - final Path cp = new Path(getProject()); - appendPath(cp, getBootclasspath()); - cp.setLocation(getDestdir().getAbsoluteFile()); - appendPath(cp, getClasspath()); - appendPath(cp, getSourcepath()); - appendPath(cp, getSrcdir()); - if (getIncludeantruntime()) { - cp.addExisting(cp.concatSystemClasspath("last")); - } - if (getIncludejavaruntime()) { - cp.addJavaRuntime(); - } - cp.addExtdirs(getExtdirs()); + cp.addExtdirs(getExtdirs()); - final String[] pathElements = cp.list(); - for (int i = 0; i < pathElements.length; i++) { - final String pathElement = pathElements[i]; - classPathBuffer.append(File.pathSeparator); - classPathBuffer.append(pathElement); - } + final String[] pathElements = cp.list(); + for (int i = 0; i < pathElements.length; i++) { + final String pathElement = pathElements[i]; + classPathBuffer.append(File.pathSeparator); + classPathBuffer.append(pathElement); + } - final String classPath = classPathBuffer.toString(); - log("classpath=" + classPath, Project.MSG_VERBOSE); + final String classPath = classPathBuffer.toString(); + log("classpath=" + classPath, Project.MSG_VERBOSE); - try { - return createInstrumentationClassFinder(classPath); - } - catch (MalformedURLException e) { - fireError(e.getMessage()); - return null; - } + try { + return createInstrumentationClassFinder(classPath); } + catch (MalformedURLException e) { + fireError(e.getMessage()); + return null; + } + } - /** - * Append path to class path if the appened path is not empty and is not null - * - * @param cp the path to modify - * @param p the path to append - */ - private void appendPath(Path cp, final Path p) { - if (p != null && p.size() > 0) { - cp.append(p); - } + /** + * Append path to class path if the appened path is not empty and is not null + * + * @param cp the path to modify + * @param p the path to append + */ + private void appendPath(Path cp, final Path p) { + if (p != null && p.size() > 0) { + cp.append(p); } + } + + /** + * Instrument classes with NotNull annotations + * + * @param dir the directory with classes to instrument (the directory is processed recursively) + * @param finder the classloader to use + * @return the amount of classes actually affected by instrumentation + */ + private int instrumentNotNull(File dir, final InstrumentationClassFinder finder) { + int instrumented = 0; + final File[] files = dir.listFiles(); + for (int i = 0; i < files.length; i++) { + File file = files[i]; + final String name = file.getName(); + if (name.endsWith(".class")) { + final String path = file.getPath(); + log("Adding @NotNull assertions to " + path, Project.MSG_VERBOSE); + try { + final FileInputStream inputStream = new FileInputStream(file); + try { + ClassReader reader = new ClassReader(inputStream); + + int version = getClassFileVersion(reader); + + if (version >= Opcodes.V1_5) { + ClassWriter writer = new InstrumenterClassWriter(getAsmClassWriterFlags(version), finder); - /** - * Instrument classes with NotNull annotations - * - * @param dir the directory with classes to instrument (the directory is processed recursively) - * @param finder the classloader to use - * @return the amount of classes actually affected by instrumentation - */ - private int instrumentNotNull(File dir, final InstrumentationClassFinder finder) { - int instrumented = 0; - final File[] files = dir.listFiles(); - for (int i = 0; i < files.length; i++) { - File file = files[i]; - final String name = file.getName(); - if (name.endsWith(".class")) { - final String path = file.getPath(); - log("Adding @NotNull assertions to " + path, Project.MSG_VERBOSE); + final NotNullVerifyingInstrumenter instrumenter = new NotNullVerifyingInstrumenter(writer); + reader.accept(instrumenter, 0); + if (instrumenter.isModification()) { + final FileOutputStream fileOutputStream = new FileOutputStream(path); try { - final FileInputStream inputStream = new FileInputStream(file); - try { - ClassReader reader = new ClassReader(inputStream); - - int version = getClassFileVersion(reader); - - if (version >= Opcodes.V1_5) { - ClassWriter writer = new InstrumenterClassWriter(getAsmClassWriterFlags(version), finder); - - final NotNullVerifyingInstrumenter instrumenter = new NotNullVerifyingInstrumenter(writer); - reader.accept(instrumenter, 0); - if (instrumenter.isModification()) { - final FileOutputStream fileOutputStream = new FileOutputStream(path); - try { - fileOutputStream.write(writer.toByteArray()); - instrumented++; - } - finally { - fileOutputStream.close(); - } - } - } - } - finally { - inputStream.close(); - } + fileOutputStream.write(writer.toByteArray()); + instrumented++; } - catch (IOException e) { - log("Failed to instrument @NotNull assertion for " + path + ": " + e.getMessage(), Project.MSG_WARN); - } - catch (Exception e) { - fireError("@NotNull instrumentation failed for " + path + ": " + e.toString()); + finally { + fileOutputStream.close(); } + } } - else if (file.isDirectory()) { - instrumented += instrumentNotNull(file, finder); - } + } + finally { + inputStream.close(); + } } - - return instrumented; + catch (IOException e) { + log("Failed to instrument @NotNull assertion for " + path + ": " + e.getMessage(), Project.MSG_WARN); + } + catch (Exception e) { + fireError("@NotNull instrumentation failed for " + path + ": " + e.toString()); + } + } + else if (file.isDirectory()) { + instrumented += instrumentNotNull(file, finder); + } } - private static int getClassFileVersion(ClassReader reader) { - final int[] classfileVersion = new int[1]; - reader.accept(new ClassVisitor(Opcodes.ASM4) { - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - classfileVersion[0] = version; - } - }, 0); + return instrumented; + } - return classfileVersion[0]; - } + private static int getClassFileVersion(ClassReader reader) { + final int[] classfileVersion = new int[1]; + reader.accept(new ClassVisitor(Opcodes.ASM4) { + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + classfileVersion[0] = version; + } + }, 0); - private void fireError(final String message) { - if (failOnError) { - throw new BuildException(message, getLocation()); - } - else { - log(message, Project.MSG_ERR); - } - } + return classfileVersion[0]; + } - private File getClassFile(String className) { - final String classOrInnerName = getClassOrInnerName(className); - if (classOrInnerName == null) return null; - return new File(getDestdir().getAbsolutePath(), classOrInnerName + ".class"); + private void fireError(final String message) { + if (failOnError) { + throw new BuildException(message, getLocation()); } - - private String getClassOrInnerName(String className) { - File classFile = new File(getDestdir().getAbsolutePath(), className + ".class"); - if (classFile.exists()) return className; - int position = className.lastIndexOf('/'); - if (position == -1) return null; - return getClassOrInnerName(className.substring(0, position) + '$' + className.substring(position + 1)); + else { + log(message, Project.MSG_ERR); } + } - protected void resetFileLists() { - super.resetFileLists(); - myFormFiles = new ArrayList(); - } + private File getClassFile(String className) { + final String classOrInnerName = getClassOrInnerName(className); + if (classOrInnerName == null) return null; + return new File(getDestdir().getAbsolutePath(), classOrInnerName + ".class"); + } - protected void scanDir(final File srcDir, final File destDir, final String[] files) { - super.scanDir(srcDir, destDir, files); - for (int i = 0; i < files.length; i++) { - final String file = files[i]; - if (file.endsWith(".form")) { - log("Found form file " + file, Project.MSG_VERBOSE); - myFormFiles.add(new File(srcDir, file)); - } - } + private String getClassOrInnerName(String className) { + File classFile = new File(getDestdir().getAbsolutePath(), className + ".class"); + if (classFile.exists()) return className; + int position = className.lastIndexOf('/'); + if (position == -1) return null; + return getClassOrInnerName(className.substring(0, position) + '$' + className.substring(position + 1)); + } + + protected void resetFileLists() { + super.resetFileLists(); + myFormFiles = new ArrayList(); + } + + protected void scanDir(final File srcDir, final File destDir, final String[] files) { + super.scanDir(srcDir, destDir, files); + for (int i = 0; i < files.length; i++) { + final String file = files[i]; + if (file.endsWith(".form")) { + log("Found form file " + file, Project.MSG_VERBOSE); + myFormFiles.add(new File(srcDir, file)); + } } + } private static InstrumentationClassFinder createInstrumentationClassFinder(final String classPath) throws MalformedURLException { final ArrayList urls = new ArrayList(); @@ -497,58 +510,58 @@ public class Javac2 extends Javac { } private class AntNestedFormLoader implements NestedFormLoader { - private final ClassLoader myLoader; - private final List myNestedFormPathList; - private final HashMap myFormCache = new HashMap(); - - public AntNestedFormLoader(final ClassLoader loader, List nestedFormPathList) { - myLoader = loader; - myNestedFormPathList = nestedFormPathList; - } + private final ClassLoader myLoader; + private final List myNestedFormPathList; + private final HashMap myFormCache = new HashMap(); - public LwRootContainer loadForm(String formFilePath) throws Exception { - if (myFormCache.containsKey(formFilePath)) { - return (LwRootContainer)myFormCache.get(formFilePath); - } + public AntNestedFormLoader(final ClassLoader loader, List nestedFormPathList) { + myLoader = loader; + myNestedFormPathList = nestedFormPathList; + } - String lowerFormFilePath = formFilePath.toLowerCase(); - log("Searching for form " + lowerFormFilePath, Project.MSG_VERBOSE); - for (Iterator iterator = myFormFiles.iterator(); iterator.hasNext();) { - File file = (File)iterator.next(); - String name = file.getAbsolutePath().replace(File.separatorChar, '/').toLowerCase(); - log("Comparing with " + name, Project.MSG_VERBOSE); - if (name.endsWith(lowerFormFilePath)) { - return loadForm(formFilePath, new FileInputStream(file)); - } - } + public LwRootContainer loadForm(String formFilePath) throws Exception { + if (myFormCache.containsKey(formFilePath)) { + return (LwRootContainer)myFormCache.get(formFilePath); + } - if (myNestedFormPathList != null) { - for (int i = 0; i < myNestedFormPathList.size(); i++) { - PrefixedPath path = (PrefixedPath)myNestedFormPathList.get(i); - File formFile = path.findFile(formFilePath); - if (formFile != null) { - return loadForm(formFilePath, new FileInputStream(formFile)); - } - } - } - InputStream resourceStream = myLoader.getResourceAsStream(formFilePath); - if (resourceStream != null) { - return loadForm(formFilePath, resourceStream); - } - throw new Exception("Cannot find nested form file " + formFilePath); + String lowerFormFilePath = formFilePath.toLowerCase(); + log("Searching for form " + lowerFormFilePath, Project.MSG_VERBOSE); + for (Iterator iterator = myFormFiles.iterator(); iterator.hasNext();) { + File file = (File)iterator.next(); + String name = file.getAbsolutePath().replace(File.separatorChar, '/').toLowerCase(); + log("Comparing with " + name, Project.MSG_VERBOSE); + if (name.endsWith(lowerFormFilePath)) { + return loadForm(formFilePath, new FileInputStream(file)); } + } - private LwRootContainer loadForm(String formFileName, InputStream resourceStream) throws Exception { - final LwRootContainer container = Utils.getRootContainer(resourceStream, null); - myFormCache.put(formFileName, container); - return container; + if (myNestedFormPathList != null) { + for (int i = 0; i < myNestedFormPathList.size(); i++) { + PrefixedPath path = (PrefixedPath)myNestedFormPathList.get(i); + File formFile = path.findFile(formFilePath); + if (formFile != null) { + return loadForm(formFilePath, new FileInputStream(formFile)); + } } + } + InputStream resourceStream = myLoader.getResourceAsStream(formFilePath); + if (resourceStream != null) { + return loadForm(formFilePath, resourceStream); + } + throw new Exception("Cannot find nested form file " + formFilePath); + } - public String getClassToBindName(LwRootContainer container) { - final String className = container.getClassToBind(); - String result = getClassOrInnerName(className.replace('.', '/')); - if (result != null) return result.replace('/', '.'); - return className; - } + private LwRootContainer loadForm(String formFileName, InputStream resourceStream) throws Exception { + final LwRootContainer container = Utils.getRootContainer(resourceStream, null); + myFormCache.put(formFileName, container); + return container; + } + + public String getClassToBindName(LwRootContainer container) { + final String className = container.getClassToBind(); + String result = getClassOrInnerName(className.replace('.', '/')); + if (result != null) return result.replace('/', '.'); + return className; } + } } diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/BuildProperties.java b/java/compiler/openapi/src/com/intellij/compiler/ant/BuildProperties.java index 51ee7d10e320..5de5c5f89058 100644 --- a/java/compiler/openapi/src/com/intellij/compiler/ant/BuildProperties.java +++ b/java/compiler/openapi/src/com/intellij/compiler/ant/BuildProperties.java @@ -57,6 +57,7 @@ public abstract class BuildProperties extends CompositeGenerator { public static final @NonNls String PROPERTY_IDEA_HOME = "idea.home"; public static final @NonNls String PROPERTY_JAVAC2_HOME = "javac2.home"; public static final @NonNls String PROPERTY_JAVAC2_CLASSPATH_ID = "javac2.classpath"; + public static final @NonNls String PROPERTY_INCLUDE_JAVA_RUNTIME_FOR_INSTRUMENTATION = "javac2.instrumentation.includeJavaRuntime"; protected abstract void createJdkGenerators(Project project); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleLineBreakpointActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleLineBreakpointActionHandler.java index 5b5615614865..561ae013e031 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleLineBreakpointActionHandler.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleLineBreakpointActionHandler.java @@ -39,6 +39,13 @@ import org.jetbrains.annotations.Nullable; public class ToggleLineBreakpointActionHandler extends DebuggerActionHandler { + private final boolean myTemporary; + + public ToggleLineBreakpointActionHandler(boolean temporary) { + + myTemporary = temporary; + } + public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) { PlaceInDocument place = getPlace(project, event); if (place != null) { @@ -78,10 +85,16 @@ public class ToggleLineBreakpointActionHandler extends DebuggerActionHandler { if(breakpoint == null) { LineBreakpoint lineBreakpoint = manager.addLineBreakpoint(document, line); if(lineBreakpoint != null) { + lineBreakpoint.REMOVE_AFTER_HIT = myTemporary; RequestManagerImpl.createRequests(lineBreakpoint); } } else { - manager.removeBreakpoint(breakpoint); + if (!breakpoint.REMOVE_AFTER_HIT && myTemporary) { + breakpoint.REMOVE_AFTER_HIT = true; + breakpoint.updateUI(); + } else { + manager.removeBreakpoint(breakpoint); + } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java index 4ce8162fcd66..c8536bef1702 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java @@ -29,6 +29,7 @@ import com.sun.jdi.ThreadReference; import com.sun.jdi.event.EventSet; import com.sun.jdi.request.EventRequest; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; @@ -108,6 +109,7 @@ public abstract class SuspendContextImpl implements SuspendContext { } + @Nullable public EventSet getEventSet() { assertNotResumed(); return myEventSet; diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java index bf78d8240163..1732e227351e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java @@ -69,7 +69,7 @@ public class DebuggerManagerImpl extends DebuggerManagerEx { private final Project myProject; private final HashMap<ProcessHandler, DebuggerSession> mySessions = new HashMap<ProcessHandler, DebuggerSession>(); private final BreakpointManager myBreakpointManager; - private final List<NameMapper> myNameMappers = ContainerUtil.createEmptyCOWList(); + private final List<NameMapper> myNameMappers = ContainerUtil.createLockFreeCopyOnWriteList(); private final List<Function<DebugProcess, PositionManager>> myCustomPositionManagerFactories = new ArrayList<Function<DebugProcess, PositionManager>>(); @@ -135,17 +135,19 @@ public class DebuggerManagerImpl extends DebuggerManagerEx { public DebuggerManagerImpl(Project project, StartupManager startupManager, final EditorColorsManager colorsManager) { myProject = project; myBreakpointManager = new BreakpointManager(myProject, startupManager, this); - final EditorColorsListener myColorsListener = new EditorColorsListener() { - public void globalSchemeChange(EditorColorsScheme scheme) { - getBreakpointManager().updateBreakpointsUI(); - } - }; - colorsManager.addEditorColorsListener(myColorsListener); - Disposer.register(project, new Disposable() { - public void dispose() { - colorsManager.removeEditorColorsListener(myColorsListener); - } - }); + if (!project.isDefault()) { + final EditorColorsListener colorsListener = new EditorColorsListener() { + public void globalSchemeChange(EditorColorsScheme scheme) { + getBreakpointManager().updateBreakpointsUI(); + } + }; + colorsManager.addEditorColorsListener(colorsListener); + Disposer.register(project, new Disposable() { + public void dispose() { + colorsManager.removeEditorColorsListener(colorsListener); + } + }); + } } public DebuggerSession getSession(DebugProcess process) { diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java index 88c3f50b3d86..908798e7dfbc 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java @@ -40,11 +40,14 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; import com.intellij.psi.*; import com.intellij.ui.classFilter.ClassFilter; +import com.intellij.util.SmartList; import com.sun.jdi.*; import com.sun.jdi.event.Event; +import com.sun.jdi.event.EventSet; import org.jdom.Attribute; import org.jdom.Element; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -332,16 +335,21 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils { return elementsEqual(root1, root2); } + @NotNull public static List<Pair<Breakpoint, Event>> getEventDescriptors(SuspendContextImpl suspendContext) { DebuggerManagerThreadImpl.assertIsManagerThread(); - if(suspendContext == null || suspendContext.getEventSet() == null) { + if(suspendContext == null) { return Collections.emptyList(); } - final List<Pair<Breakpoint, Event>> eventDescriptors = new ArrayList<Pair<Breakpoint, Event>>(); + final EventSet events = suspendContext.getEventSet(); + if(events == null) { + return Collections.emptyList(); + } + final List<Pair<Breakpoint, Event>> eventDescriptors = new SmartList<Pair<Breakpoint, Event>>(); final RequestManagerImpl requestManager = suspendContext.getDebugProcess().getRequestsManager(); - for (final Event event : suspendContext.getEventSet()) { - Requestor requestor = requestManager.findRequestor(event.request()); + for (final Event event : events) { + final Requestor requestor = requestManager.findRequestor(event.request()); if (requestor instanceof Breakpoint) { eventDescriptors.add(new Pair<Breakpoint, Event>((Breakpoint)requestor, event)); } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java index e97b4bf7b8bb..b045b364bf08 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java @@ -23,6 +23,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.Nullable; @@ -59,21 +60,27 @@ public class JavaEditorTextProviderImpl implements EditorTextProvider { @Nullable private static PsiElement findExpression(PsiElement element) { - if (!(element instanceof PsiIdentifier || element instanceof PsiKeyword)) { - return null; - } - PsiElement parent = element.getParent(); - if (parent instanceof PsiVariable) { - return element; + PsiElement e = PsiTreeUtil.getParentOfType(element, PsiVariable.class, PsiExpression.class); + if (e instanceof PsiVariable) { + e = ((PsiVariable)e).getNameIdentifier(); } - if (parent instanceof PsiReferenceExpression) { - if (parent.getParent() instanceof PsiCallExpression) return parent.getParent(); - return parent; + else if (e instanceof PsiReferenceExpression) { + if (e.getParent() instanceof PsiCallExpression) { + e = e.getParent(); + } + else if (e.getParent() instanceof PsiReferenceExpression) { + // <caret>System.out case should not return plain class name + PsiElement resolve = ((PsiReferenceExpression)e).resolve(); + if (resolve instanceof PsiClass) { + e = e.getParent(); + } + } } - if (parent instanceof PsiThisExpression) { - return parent; + if (e instanceof PsiNewExpression) { + // skip new Runnable() { ... } + if (((PsiNewExpression)e).getAnonymousClass() != null) return null; } - return null; + return e; } @Nullable diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/descriptors/data/ThrownExceptionValueData.java b/java/debugger/impl/src/com/intellij/debugger/impl/descriptors/data/ThrownExceptionValueData.java new file mode 100644 index 000000000000..5c8610255f22 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/impl/descriptors/data/ThrownExceptionValueData.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2013 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.debugger.impl.descriptors.data; + +import com.intellij.debugger.ui.impl.watch.ThrownExceptionValueDescriptorImpl; +import com.intellij.openapi.project.Project; +import com.sun.jdi.ObjectReference; +import org.jetbrains.annotations.NotNull; + +public final class ThrownExceptionValueData extends DescriptorData<ThrownExceptionValueDescriptorImpl>{ + @NotNull + private final ObjectReference myExceptionObj; + + public ThrownExceptionValueData(@NotNull ObjectReference exceptionObj) { + myExceptionObj = exceptionObj; + } + + protected ThrownExceptionValueDescriptorImpl createDescriptorImpl(Project project) { + return new ThrownExceptionValueDescriptorImpl(project, myExceptionObj); + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ThrownExceptionValueData data = (ThrownExceptionValueData)o; + + if (!myExceptionObj.equals(data.myExceptionObj)) return false; + + return true; + } + + @Override + public int hashCode() { + return myExceptionObj.hashCode(); + } + + public DisplayKey<ThrownExceptionValueDescriptorImpl> getDisplayKey() { + return new SimpleDisplayKey<ThrownExceptionValueDescriptorImpl>(myExceptionObj); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerExpressionComboBox.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerExpressionComboBox.java index 9f9cf4a34075..408dc1aeb04e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerExpressionComboBox.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerExpressionComboBox.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -22,9 +22,11 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.ui.EditorComboBoxEditor; import com.intellij.ui.EditorComboBoxRenderer; +import com.intellij.ui.EditorTextField; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -90,6 +92,7 @@ public class DebuggerExpressionComboBox extends DebuggerEditorImpl { myComboBox.setLightWeightPopupEnabled(false); myEditor = new MyEditorComboBoxEditor(getProject(), getCurrentFactory().getFileType()); + //noinspection GtkPreferredJComboBoxRenderer myComboBox.setRenderer(new EditorComboBoxRenderer(myEditor)); myComboBox.setEditable(true); @@ -98,7 +101,7 @@ public class DebuggerExpressionComboBox extends DebuggerEditorImpl { } public void selectPopupValue() { - selectAll(); + //selectAll(); final Object currentPopupValue = getCurrentPopupValue(); if (currentPopupValue != null) { myComboBox.getModel().setSelectedItem(currentPopupValue); @@ -133,7 +136,7 @@ public class DebuggerExpressionComboBox extends DebuggerEditorImpl { final String itemText = item.getText().replace('\n', ' '); restoreFactory(item); item.setText(itemText); - if (!"".equals(itemText)) { + if (!StringUtil.isEmpty(itemText)) { if (myComboBox.getItemCount() == 0 || !item.equals(myComboBox.getItemAt(0))) { myComboBox.insertItemAt(item, 0); } @@ -204,16 +207,32 @@ public class DebuggerExpressionComboBox extends DebuggerEditorImpl { } public JComponent getEditorComponent() { - return (JComponent)myEditor.getEditorComponent(); + return myEditor.getEditorComponent(); } public void addRecent(TextWithImports text) { if (text.getText().length() != 0) { - final Component editorComponent = myComboBox.getEditor().getEditorComponent(); + Component editorComponent = myComboBox.getEditor().getEditorComponent(); final boolean focusOwner = editorComponent.isFocusOwner(); + int offset = -1; + if (editorComponent instanceof EditorTextField) { + final EditorTextField textField = (EditorTextField)editorComponent; + if (textField.getEditor() != null) { + offset = textField.getCaretModel().getOffset(); + } + } super.addRecent(text); myComboBox.insertItemAt(text, 0); myComboBox.setSelectedIndex(0); + editorComponent = myComboBox.getEditor().getEditorComponent(); + if (offset != -1 && editorComponent instanceof EditorTextField) { + final EditorTextField textField = (EditorTextField)editorComponent; + final Editor editor = textField.getEditor(); + if (editor != null) { + textField.getCaretModel().moveToOffset(offset); + editor.getSelectionModel().setSelection(offset, offset); + } + } if (focusOwner) { editorComponent.requestFocus(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/ExpressionEvaluationDialog.java b/java/debugger/impl/src/com/intellij/debugger/ui/ExpressionEvaluationDialog.java index 38bff6101d8f..a4e1b1675c13 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/ExpressionEvaluationDialog.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/ExpressionEvaluationDialog.java @@ -28,9 +28,11 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CustomShortcutSet; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ex.AbstractDelegatingToRootTraversalPolicy; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.components.JBLabel; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; @@ -44,8 +46,8 @@ public class ExpressionEvaluationDialog extends EvaluationDialog { super(project, defaultExpression); setTitle(DebuggerBundle.message("evaluate.expression.dialog.title")); - final KeyStroke expressionStroke = KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.ALT_MASK); - final KeyStroke resultStroke = KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.ALT_MASK); + final KeyStroke expressionStroke = KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.ALT_MASK); + final KeyStroke resultStroke = KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.ALT_MASK); final JRootPane rootPane = getRootPane(); @@ -99,6 +101,30 @@ public class ExpressionEvaluationDialog extends EvaluationDialog { panel.add(exprPanel, BorderLayout.NORTH); panel.add(resultPanel, BorderLayout.CENTER); + + panel.setFocusTraversalPolicyProvider(true); + panel.setFocusTraversalPolicy(new AbstractDelegatingToRootTraversalPolicy() { + @Override + public Component getComponentBefore(Container aContainer, Component aComponent) { + boolean focusExpressionCombo = isParent(aComponent, getEvaluationPanel()); + return focusExpressionCombo ? getExpressionCombo().getEditorComponent() : super.getComponentBefore(aContainer, aComponent); + } + + @Override + public Component getComponentAfter(Container aContainer, Component aComponent) { + boolean focusEvaluationPanel = isParent(aComponent, exprPanel); + return focusEvaluationPanel ? getEvaluationPanel().getTree() : super.getComponentAfter(aContainer, aComponent); + } + + private boolean isParent(@NotNull Component component, @NotNull Container parent) { + for (Component c = component; c != null; c = c.getParent()) { + if (c == parent) { + return true; + } + } + return false; + } + }); return panel; } @@ -112,6 +138,7 @@ public class ExpressionEvaluationDialog extends EvaluationDialog { return (DebuggerExpressionComboBox)getEditor(); } + @NotNull protected Action[] createActions() { return new Action[] { getOKAction(), getCancelAction(), new SwitchAction(), getHelpAction() } ; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java index 7683bc16b110..9c61c8c73fe5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java @@ -59,7 +59,7 @@ import java.util.concurrent.atomic.AtomicReference; * Time: 6:00:55 PM */ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent { - private final List<HotSwapVetoableListener> myListeners = ContainerUtil.createEmptyCOWList(); + private final List<HotSwapVetoableListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); private boolean myAskBeforeHotswap = true; private final Project myProject; private boolean myPerformHotswapAfterThisCompilation = true; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java index 9ae2a3d9893e..7b2948a4adfa 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java @@ -64,7 +64,8 @@ public class JavaDebuggerSupport extends DebuggerSupport { private final ForceRunToCursorActionHandler myForceRunToCursorActionHandler = new ForceRunToCursorActionHandler(); private final ResumeActionHandler myResumeActionHandler = new ResumeActionHandler(); private final PauseActionHandler myPauseActionHandler = new PauseActionHandler(); - private final ToggleLineBreakpointActionHandler myToggleLineBreakpointActionHandler = new ToggleLineBreakpointActionHandler(); + private final ToggleLineBreakpointActionHandler myToggleLineBreakpointActionHandler = new ToggleLineBreakpointActionHandler(false); + private final ToggleLineBreakpointActionHandler myToggleTemporaryLineBreakpointActionHandler = new ToggleLineBreakpointActionHandler(true); private final ShowExecutionPointActionHandler myShowExecutionPointActionHandler = new ShowExecutionPointActionHandler(); private final EvaluateActionHandler myEvaluateActionHandler = new EvaluateActionHandler(); private final QuickEvaluateActionHandler myQuickEvaluateHandler = new QuickEvaluateActionHandler(); @@ -136,6 +137,12 @@ public class JavaDebuggerSupport extends DebuggerSupport { } @NotNull + @Override + public DebuggerActionHandler getToggleTemporaryLineBreakpointHandler() { + return myToggleTemporaryLineBreakpointActionHandler; + } + + @NotNull public DebuggerActionHandler getShowExecutionPointHandler() { return myShowExecutionPointActionHandler; } @@ -185,7 +192,7 @@ public class JavaDebuggerSupport extends DebuggerSupport { } private static class JavaBreakpointPanelProvider extends BreakpointPanelProvider<Breakpoint> { - private List<MyBreakpointManagerListener> myListeners = ContainerUtil.createEmptyCOWList(); + private List<MyBreakpointManagerListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); @Override public AnAction[] getAddBreakpointActions(@NotNull Project project) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java index b738089d0a64..58b1917b57a1 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java @@ -35,6 +35,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; import com.intellij.psi.PsiClass; import com.intellij.util.StringBuilderSpinAllocator; +import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import com.sun.jdi.ObjectReference; import com.sun.jdi.ReferenceType; import com.sun.jdi.Value; @@ -52,6 +53,7 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa public boolean ENABLED = true; public boolean LOG_ENABLED = false; public boolean LOG_EXPRESSION_ENABLED = false; + public boolean REMOVE_AFTER_HIT = false; private TextWithImports myLogMessage; // an expression to be evaluated and printed @NonNls private static final String LOG_MESSAGE_OPTION_NAME = "LOG_MESSAGE"; public static final Breakpoint[] EMPTY_ARRAY = new Breakpoint[0]; @@ -204,6 +206,7 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa } private void runAction(final EvaluationContextImpl context, LocatableEvent event) { + final DebugProcessImpl debugProcess = context.getDebugProcess(); if (LOG_ENABLED || LOG_EXPRESSION_ENABLED) { final StringBuilder buf = StringBuilderSpinAllocator.alloc(); try { @@ -211,7 +214,6 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa buf.append(getEventMessage(event)); buf.append("\n"); } - final DebugProcessImpl debugProcess = context.getDebugProcess(); final TextWithImports expressionToEvaluate = getLogMessage(); if (LOG_EXPRESSION_ENABLED && expressionToEvaluate != null && !"".equals(expressionToEvaluate.getText())) { if(!debugProcess.isAttached()) { @@ -246,6 +248,20 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa StringBuilderSpinAllocator.dispose(buf); } } + if (REMOVE_AFTER_HIT) { + debugProcess.addDebugProcessListener(new DebugProcessAdapter() { + @Override + public void resumed(SuspendContext suspendContext) { + DebuggerUIUtil.invokeOnEventDispatch(new Runnable() { + @Override + public void run() { + DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(Breakpoint.this); + } + }); + debugProcess.removeDebugProcessListener(this); + } + }); + } } public final void updateUI() { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java index 8c77bc1c4440..32c3637c2f4c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java @@ -175,7 +175,7 @@ public class BreakpointManager implements JDOMExternalizable { @Nullable private EditorMouseEvent myMousePressedEvent; @Nullable - private Breakpoint toggleBreakpoint(final boolean mostSuitingBreakpoint, final int line) { + private Breakpoint toggleBreakpoint(final boolean mostSuitingBreakpoint, final int line, boolean temporary) { final Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor(); if (editor == null) { return null; @@ -223,6 +223,7 @@ public class BreakpointManager implements JDOMExternalizable { } if (breakpoint != null) { + breakpoint.REMOVE_AFTER_HIT = temporary; RequestManagerImpl.createRequests(breakpoint); } return breakpoint; @@ -305,10 +306,13 @@ public class BreakpointManager implements JDOMExternalizable { DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { @Override public void run() { - final Breakpoint breakpoint = toggleBreakpoint(e.getMouseEvent().isAltDown(), line); + final boolean suitingBreakpoint = e.getMouseEvent().isAltDown() && !e.getMouseEvent().isShiftDown(); + final boolean temporary = e.getMouseEvent().isAltDown() && e.getMouseEvent().isShiftDown(); + final Breakpoint breakpoint = toggleBreakpoint(suitingBreakpoint, line, temporary); - if (e.getMouseEvent().isShiftDown() && breakpoint != null) { + + if (!e.getMouseEvent().isAltDown() && e.getMouseEvent().isShiftDown() && breakpoint != null) { breakpoint.LOG_EXPRESSION_ENABLED = true; String selection = editor.getSelectionModel().getSelectedText(); String text = selection != null ? selection : DebuggerBundle.message("breakpoint.log.message", diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form index 7d71e2166522..84f5c3246a41 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form @@ -105,7 +105,7 @@ <properties/> <border type="none"/> <children> - <grid id="1d1c" binding="myActionsPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="1d1c" binding="myActionsPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="5"/> <constraints> <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> @@ -168,6 +168,14 @@ </component> </children> </grid> + <component id="50916" class="javax.swing.JCheckBox" binding="myTemporaryCheckBox" default-binding="true"> + <constraints> + <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <text value="&Temporary"/> + </properties> + </component> </children> </grid> <xy id="862d9" binding="mySpecialBoxPanel" layout-manager="XYLayout" hgap="-1" vgap="-1"> diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java index 78abfe4cad61..4aa904106d03 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java @@ -116,6 +116,7 @@ public abstract class BreakpointPropertiesPanel { private JPanel myConditionsPanel; private JPanel myActionsPanel; private JBCheckBox myConditionCheckbox; + private JCheckBox myTemporaryCheckBox; ButtonGroup mySuspendPolicyGroup; public static final String CONTROL_LOG_MESSAGE = "logMessage"; @@ -378,6 +379,7 @@ public abstract class BreakpointPropertiesPanel { IJSwingUtilities.adjustComponentsOnMac(myCbSuspend); IJSwingUtilities.adjustComponentsOnMac(myLogExpressionCheckBox); IJSwingUtilities.adjustComponentsOnMac(myLogMessageCheckBox); + IJSwingUtilities.adjustComponentsOnMac(myTemporaryCheckBox); } private List<BreakpointItem> getBreakpointItemsExceptMy() { @@ -507,8 +509,10 @@ public abstract class BreakpointPropertiesPanel { } }); myLogMessageCheckBox.setSelected(breakpoint.LOG_ENABLED); + myTemporaryCheckBox.setSelected(breakpoint.REMOVE_AFTER_HIT); + myTemporaryCheckBox.setVisible(breakpoint instanceof LineBreakpoint); myLogExpressionCheckBox.setSelected(breakpoint.LOG_EXPRESSION_ENABLED); - if (breakpoint.LOG_ENABLED || breakpoint.LOG_EXPRESSION_ENABLED) { + if (breakpoint.LOG_ENABLED || breakpoint.LOG_EXPRESSION_ENABLED || (breakpoint instanceof LineBreakpoint && breakpoint.REMOVE_AFTER_HIT)) { actionsPanelVisible = true; } @@ -622,6 +626,7 @@ public abstract class BreakpointPropertiesPanel { breakpoint.setLogMessage(myLogExpressionCombo.getText()); breakpoint.LOG_EXPRESSION_ENABLED = !breakpoint.getLogMessage().isEmpty() && myLogExpressionCheckBox.isSelected(); breakpoint.LOG_ENABLED = myLogMessageCheckBox.isSelected(); + breakpoint.REMOVE_AFTER_HIT = myTemporaryCheckBox.isSelected(); breakpoint.SUSPEND = myCbSuspend.isSelected(); breakpoint.SUSPEND_POLICY = getSelectedSuspendPolicy(); reloadInstanceFilters(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java index de3b91837017..2be7f168b446 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java @@ -87,6 +87,9 @@ public class LineBreakpoint extends BreakpointWithHighlighter { } protected Icon getSetIcon(boolean isMuted) { + if (REMOVE_AFTER_HIT) { + return isMuted ? AllIcons.Debugger.Db_muted_temporary_breakpoint : AllIcons.Debugger.Db_temporary_breakpoint; + } return isMuted? AllIcons.Debugger.Db_muted_breakpoint : AllIcons.Debugger.Db_set_breakpoint; } @@ -95,6 +98,9 @@ public class LineBreakpoint extends BreakpointWithHighlighter { } protected Icon getVerifiedIcon(boolean isMuted) { + if (REMOVE_AFTER_HIT) { + return isMuted ? AllIcons.Debugger.Db_muted_temporary_breakpoint : AllIcons.Debugger.Db_temporary_breakpoint; + } return isMuted? AllIcons.Debugger.Db_muted_verified_breakpoint : AllIcons.Debugger.Db_verified_breakpoint; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java index 5a8f0c1066a0..d9f7c1838793 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -99,16 +99,11 @@ public class TipManager implements Disposable, PopupMenuListener { } } - private class MyFrameStateListener implements FrameStateListener { + private class MyFrameStateListener extends FrameStateListener.Adapter { @Override public void onFrameDeactivated() { hideTooltip(true); } - - @Override - public void onFrameActivated() { - //Do nothing - } } public JPopupMenu registerPopup(JPopupMenu menu) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/WatchDebuggerTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/WatchDebuggerTree.java index 8282adf8f2b4..12e5b1c7fa9b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/WatchDebuggerTree.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/WatchDebuggerTree.java @@ -75,8 +75,7 @@ public class WatchDebuggerTree extends DebuggerTree { public DebuggerTreeNodeImpl addWatch(TextWithImports text, @Nullable String customName) { ApplicationManager.getApplication().assertIsDispatchThread(); final DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl) getModel().getRoot(); - final WatchItemDescriptor descriptor = new WatchItemDescriptor(getProject(), text); - descriptor.setCustomName(customName); + final WatchItemDescriptor descriptor = new WatchItemDescriptor(getProject(), text, customName); DebuggerTreeNodeImpl node = DebuggerTreeNodeImpl.createNodeNoUpdate(this, descriptor); root.add(node); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java index e80bf60ebad0..06ca84038da2 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java @@ -31,12 +31,14 @@ import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.jdi.LocalVariableProxyImpl; import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl; import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.settings.ThreadsViewSettings; +import com.intellij.debugger.ui.breakpoints.Breakpoint; import com.intellij.debugger.ui.impl.DebuggerTreeBase; import com.intellij.debugger.ui.impl.tree.TreeBuilder; import com.intellij.debugger.ui.impl.tree.TreeBuilderNode; @@ -56,6 +58,8 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.SpeedSearchComparator; import com.intellij.ui.TreeSpeedSearch; import com.sun.jdi.*; +import com.sun.jdi.event.Event; +import com.sun.jdi.event.ExceptionEvent; import javax.swing.*; import javax.swing.event.TreeModelEvent; @@ -482,6 +486,19 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi final DebuggerTreeNodeImpl methodReturnValueNode = myNodeManager.createNode(returnValueDescriptor, evaluationContext); myChildren.add(1, methodReturnValueNode); } + // add context exceptions + for (Pair<Breakpoint, Event> pair : DebuggerUtilsEx.getEventDescriptors(getSuspendContext())) { + final Event debugEvent = pair.getSecond(); + if (debugEvent instanceof ExceptionEvent) { + final ObjectReference exception = ((ExceptionEvent)debugEvent).exception(); + if (exception != null) { + final ValueDescriptorImpl exceptionDescriptor = myNodeManager.getThrownExceptionObjectDescriptor(stackDescriptor, exception); + final DebuggerTreeNodeImpl exceptionNode = myNodeManager.createNode(exceptionDescriptor, evaluationContext); + myChildren.add(1, exceptionNode); + } + } + } + } catch (EvaluateException e) { myChildren.clear(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java index 9596b397b222..ba0c43f4c3e4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java @@ -172,6 +172,10 @@ public class NodeDescriptorFactoryImpl implements NodeDescriptorFactory { return getDescriptor(parent, new MethodReturnValueData(method, value)); } + public ValueDescriptorImpl getThrownExceptionObjectDescriptor(NodeDescriptorImpl parent, ObjectReference exceptionObject) { + return getDescriptor(parent, new ThrownExceptionValueData(exceptionObject)); + } + public ThreadDescriptorImpl getThreadDescriptor(NodeDescriptorImpl parent, ThreadReferenceProxyImpl thread) { return getDescriptor(parent, new ThreadData(thread)); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ThrownExceptionValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ThrownExceptionValueDescriptorImpl.java new file mode 100644 index 000000000000..1cb48edbbc4c --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ThrownExceptionValueDescriptorImpl.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2013 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.debugger.ui.impl.watch; + +import com.intellij.debugger.DebuggerContext; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiExpression; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.Type; +import com.sun.jdi.Value; +import org.jetbrains.annotations.NotNull; + +/** + * User: lex + * Date: Oct 8, 2003 + * Time: 5:08:07 PM + */ +public class ThrownExceptionValueDescriptorImpl extends ValueDescriptorImpl{ + @NotNull + private final ObjectReference myExceptionObj; + + public ThrownExceptionValueDescriptorImpl(Project project, @NotNull ObjectReference exceptionObj) { + super(project); + myExceptionObj = exceptionObj; + // deliberately force default renderer as it does not invoke methods for rendering + // calling methods on exception object at this moment may lead to VM hang + setRenderer(DebugProcessImpl.getDefaultRenderer(exceptionObj)); + } + + public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException { + return myExceptionObj; + } + + public String getName() { + return "Exception"; + } + + @NotNull + @Override + public Type getType() { + return myExceptionObj.referenceType(); + } + + public String calcValueName() { + return getName(); + } + + public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException { + throw new EvaluateException("Evaluation not supported for thrown exception object"); + } + + public boolean canSetValue() { + return false; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/WatchItemDescriptor.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/WatchItemDescriptor.java index eaeab2d99990..30f5169fbd1e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/WatchItemDescriptor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/WatchItemDescriptor.java @@ -39,15 +39,25 @@ import org.jetbrains.annotations.Nullable; public class WatchItemDescriptor extends EvaluationDescriptor { @Nullable - private String myCustomName = null; + private final String myCustomName; public WatchItemDescriptor(Project project, TextWithImports text) { + this(project, text, (String)null); + } + + public WatchItemDescriptor(Project project, TextWithImports text, @Nullable String customName) { super(text, project); + myCustomName = customName; setValueLabel(""); } public WatchItemDescriptor(Project project, TextWithImports text, Value value) { + this(project, text, value, null); + } + + public WatchItemDescriptor(Project project, TextWithImports text, Value value, @Nullable String customName) { super(text, project, value); + myCustomName = customName; setValueLabel(""); } @@ -56,10 +66,6 @@ public class WatchItemDescriptor extends EvaluationDescriptor { return customName == null? getEvaluationText().getText() : customName; } - public void setCustomName(@Nullable String customName) { - myCustomName = customName; - } - public void setNew() { myIsNew = true; } diff --git a/java/execution/impl/src/com/intellij/execution/RunConfigurationExtension.java b/java/execution/impl/src/com/intellij/execution/RunConfigurationExtension.java index 2353f470ff43..77d2b2db429d 100644 --- a/java/execution/impl/src/com/intellij/execution/RunConfigurationExtension.java +++ b/java/execution/impl/src/com/intellij/execution/RunConfigurationExtension.java @@ -37,7 +37,7 @@ import org.jetbrains.annotations.Nullable; public abstract class RunConfigurationExtension extends RunConfigurationExtensionBase<RunConfigurationBase>{ public static final ExtensionPointName<RunConfigurationExtension> EP_NAME = new ExtensionPointName<RunConfigurationExtension>("com.intellij.runConfigurationExtension"); - public abstract <T extends RunConfigurationBase > void updateJavaParameters(final T configuration, final JavaParameters params, RunnerSettings runnerSettings); + public abstract <T extends RunConfigurationBase > void updateJavaParameters(final T configuration, final JavaParameters params, RunnerSettings runnerSettings) throws ExecutionException; @Override diff --git a/java/execution/openapi/src/com/intellij/execution/JavaExecutionUtil.java b/java/execution/openapi/src/com/intellij/execution/JavaExecutionUtil.java index 52a705e3841f..801740dec5f7 100644 --- a/java/execution/openapi/src/com/intellij/execution/JavaExecutionUtil.java +++ b/java/execution/openapi/src/com/intellij/execution/JavaExecutionUtil.java @@ -106,7 +106,7 @@ public class JavaExecutionUtil { } @Nullable - public static String getRuntimeQualifiedName(final PsiClass aClass) { + public static String getRuntimeQualifiedName(@NotNull final PsiClass aClass) { return ClassUtil.getJVMClassName(aClass); } diff --git a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java index 73192a6138d5..604d5f7f0f78 100644 --- a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java +++ b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,14 @@ import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.ModuleRootAdapter; +import com.intellij.openapi.roots.ModuleRootEvent; +import com.intellij.openapi.roots.ModuleRootModificationUtil; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService; import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; @@ -89,7 +92,7 @@ public class SetupSDKNotificationProvider extends EditorNotifications.Provider<E ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { - final Module module = ModuleUtil.findModuleForPsiElement(file); + final Module module = ModuleUtilCore.findModuleForPsiElement(file); if (module != null) { ModuleRootModificationUtil.setSdkInherited(module); } diff --git a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java index 3fd89d63820d..f0610780dbbe 100644 --- a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java +++ b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java @@ -43,14 +43,13 @@ import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.wm.*; import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.openapi.wm.impl.IdeFrameImpl; import com.intellij.pom.java.LanguageLevel; -import com.intellij.ui.mac.MacMainFrameDecorator; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -199,13 +198,13 @@ public class NewProjectUtil { if (newProject != projectToClose) { ProjectUtil.updateLastProjectLocation(projectFilePath); - if (SystemInfo.isMacOSLion) { + if (WindowManager.isFullScreenSupportedInCurrentOS()) { IdeFocusManager instance = IdeFocusManager.findInstance(); IdeFrame lastFocusedFrame = instance.getLastFocusedFrame(); if (lastFocusedFrame != null) { boolean fullScreen = WindowManagerEx.getInstanceEx().isFullScreen((Frame)lastFocusedFrame); if (fullScreen) { - newProject.putUserData(MacMainFrameDecorator.SHOULD_OPEN_IN_FULLSCREEN, Boolean.TRUE); + newProject.putUserData(IdeFrameImpl.SHOULD_OPEN_IN_FULLSCREEN, Boolean.TRUE); } } } diff --git a/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteManager.java b/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteManager.java index b44eeb1335d7..6612b41e59ba 100644 --- a/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteManager.java +++ b/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteManager.java @@ -51,9 +51,9 @@ public class PaletteManager implements ProjectComponent { private final FileEditorManager myFileEditorManager; private PaletteWindow myPaletteWindow; private ToolWindow myPaletteToolWindow; - private final List<KeyListener> myKeyListeners = ContainerUtil.createEmptyCOWList(); - private final List<PaletteDragEventListener> myDragEventListeners = ContainerUtil.createEmptyCOWList(); - private final List<ListSelectionListener> mySelectionListeners = ContainerUtil.createEmptyCOWList(); + private final List<KeyListener> myKeyListeners = ContainerUtil.createLockFreeCopyOnWriteList(); + private final List<PaletteDragEventListener> myDragEventListeners = ContainerUtil.createLockFreeCopyOnWriteList(); + private final List<ListSelectionListener> mySelectionListeners = ContainerUtil.createLockFreeCopyOnWriteList(); public PaletteManager(Project project, FileEditorManager fileEditorManager) { myProject = project; diff --git a/java/idea-ui/src/com/intellij/ide/util/importProject/ModuleInsight.java b/java/idea-ui/src/com/intellij/ide/util/importProject/ModuleInsight.java index 816878d5a06f..6d017bb38514 100644 --- a/java/idea-ui/src/com/intellij/ide/util/importProject/ModuleInsight.java +++ b/java/idea-ui/src/com/intellij/ide/util/importProject/ModuleInsight.java @@ -26,6 +26,7 @@ import com.intellij.util.StringBuilderSpinAllocator; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.StringInterner; import com.intellij.util.text.CharArrayCharSequence; +import com.intellij.util.text.StringFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -419,7 +420,7 @@ public abstract class ModuleInsight { myProgress.setText2(file.getName()); try { final char[] chars = FileUtil.loadFileText(file); - scanSourceFileForImportedPackages(new CharArrayCharSequence(chars), new Consumer<String>() { + scanSourceFileForImportedPackages(StringFactory.createShared(chars), new Consumer<String>() { public void consume(final String s) { usedPackages.add(myInterner.intern(s)); } diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectTypesList.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectTypesList.java index b292f2dcfa27..42b485df4432 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectTypesList.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectTypesList.java @@ -63,7 +63,7 @@ public class ProjectTypesList implements Disposable { private MinusculeMatcher myMatcher; private Pair<TemplateItem, Integer> myBestMatch; - private final TemplateItem myLoadingItem; + private TemplateItem myLoadingItem; public ProjectTypesList(JBList list, SearchTextField searchField, MultiMap<TemplatesGroup, ProjectTemplate> map, final WizardContext context) { myList = list; @@ -71,7 +71,7 @@ public class ProjectTypesList implements Disposable { List<TemplateItem> items = buildItems(map); final RemoteTemplatesFactory factory = new RemoteTemplatesFactory(); - final String groupName = factory.getGroups()[0]; + final String groupName = RemoteTemplatesFactory.SAMPLES_GALLERY; final TemplatesGroup samplesGroup = new TemplatesGroup(groupName, "", null); myLoadingItem = new TemplateItem(new LoadingProjectTemplate(), samplesGroup) { @Override diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateSettings.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateSettings.java index ce257cc51809..b2e2df52e764 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateSettings.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateSettings.java @@ -59,6 +59,7 @@ public class SelectTemplateSettings implements PersistentStateComponent<SelectTe @Override public void loadState(SelectTemplateSettings state) { EXPERT_MODE = state.EXPERT_MODE; + LAST_TEMPLATE = state.LAST_TEMPLATE; } public boolean EXPERT_MODE = false; diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/JavaSettingsStep.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/JavaSettingsStep.java index 786f83292c21..5f09d45bd01b 100644 --- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/JavaSettingsStep.java +++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/JavaSettingsStep.java @@ -52,34 +52,38 @@ public class JavaSettingsStep extends SdkSettingsStep { myModuleBuilder = moduleBuilder; if (moduleBuilder instanceof JavaModuleBuilder) { - Project project = settingsStep.getContext().getProject(); - ComponentWithBrowseButton.BrowseFolderActionListener<JTextField> listener = - new ComponentWithBrowseButton.BrowseFolderActionListener<JTextField>( - IdeBundle.message("prompt.select.source.directory"), null, mySourcePath, project, BrowseFilesListener.SINGLE_DIRECTORY_DESCRIPTOR, - TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT) { - @Override - protected void onFileChoosen(VirtualFile chosenFile) { - String contentEntryPath = myModuleBuilder.getContentEntryPath(); - String path = chosenFile.getPath(); - if (contentEntryPath != null) { + addSourcePath(settingsStep); + } + } - int i = StringUtil.commonPrefixLength(contentEntryPath, path); - mySourcePath.setText(path.substring(i)); - } - else { - mySourcePath.setText(path); - } - } - }; - mySourcePath.addBrowseFolderListener(project, listener); - myCreateSourceRoot.addActionListener(new ActionListener() { + private void addSourcePath(SettingsStep settingsStep) { + Project project = settingsStep.getContext().getProject(); + ComponentWithBrowseButton.BrowseFolderActionListener<JTextField> listener = + new ComponentWithBrowseButton.BrowseFolderActionListener<JTextField>( + IdeBundle.message("prompt.select.source.directory"), null, mySourcePath, project, BrowseFilesListener.SINGLE_DIRECTORY_DESCRIPTOR, + TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT) { @Override - public void actionPerformed(ActionEvent e) { - mySourcePath.setEnabled(myCreateSourceRoot.isSelected()); + protected void onFileChoosen(VirtualFile chosenFile) { + String contentEntryPath = myModuleBuilder.getContentEntryPath(); + String path = chosenFile.getPath(); + if (contentEntryPath != null) { + + int i = StringUtil.commonPrefixLength(contentEntryPath, path); + mySourcePath.setText(path.substring(i)); + } + else { + mySourcePath.setText(path); + } } - }); - settingsStep.addExpertPanel(myPanel); - } + }; + mySourcePath.addBrowseFolderListener(project, listener); + myCreateSourceRoot.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + mySourcePath.setEnabled(myCreateSourceRoot.isSelected()); + } + }); + settingsStep.addExpertPanel(myPanel); } @Override diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/SdkSettingsStep.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/SdkSettingsStep.java index 77a2158e934e..0b2f4cba1e7f 100644 --- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/SdkSettingsStep.java +++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/SdkSettingsStep.java @@ -17,7 +17,6 @@ package com.intellij.ide.util.projectWizard; import com.intellij.CommonBundle; import com.intellij.ide.IdeBundle; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; @@ -103,18 +102,22 @@ public class SdkSettingsStep extends ModuleWizardStep { @Override public boolean validate() throws ConfigurationException { - if (myJdkComboBox.getSelectedJdk() == null && !ApplicationManager.getApplication().isUnitTestMode()) { - int result = Messages.showDialog(getNoSdkMessage(), + if (myJdkComboBox.getSelectedJdk() == null) { + if (Messages.showDialog(getNoSdkMessage(), IdeBundle.message("title.no.jdk.specified"), - new String[]{CommonBundle.getYesButtonText(), CommonBundle.getNoButtonText()}, 1, Messages.getWarningIcon()); - if (result != Messages.YES) { + new String[]{CommonBundle.getYesButtonText(), CommonBundle.getNoButtonText()}, 1, Messages.getWarningIcon()) != Messages.YES) { return false; } } try { - myModel.apply(); + myModel.apply(null, true); } catch (ConfigurationException e) { //IDEA-98382 We should allow Next step if user has wrong SDK + if (Messages.showDialog(e.getMessage() + "/nDo you want to proceed?", + e.getTitle(), + new String[]{CommonBundle.getYesButtonText(), CommonBundle.getNoButtonText()}, 1, Messages.getWarningIcon()) != Messages.YES) { + return false; + } } return true; } diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/JavaSourceRootDetector.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/JavaSourceRootDetector.java index 9b077fefd04f..460d7f50b1ad 100644 --- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/JavaSourceRootDetector.java +++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/JavaSourceRootDetector.java @@ -18,6 +18,7 @@ package com.intellij.ide.util.projectWizard.importSources; import com.intellij.ide.util.projectWizard.importSources.util.CommonSourceRootDetectionUtil; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.util.NullableFunction; import org.jetbrains.annotations.NotNull; @@ -35,10 +36,10 @@ public abstract class JavaSourceRootDetector extends ProjectStructureDetector { final String fileExtension = getFileExtension(); for (File child : children) { if (child.isFile()) { - String extension = FileUtil.getExtension(child.getName()); - if (extension.equals(fileExtension)) { + if (FileUtilRt.extensionEquals(child.getName(), fileExtension)) { Pair<File, String> root = CommonSourceRootDetectionUtil.IO_FILE.suggestRootForFileWithPackageStatement(child, base, - getPackageNameFetcher(), true); + getPackageNameFetcher(), + true); if (root != null) { result.add(new JavaModuleSourceRoot(root.getFirst(), root.getSecond(), getLanguageName())); return DirectoryProcessingResult.skipChildrenAndParentsUpTo(root.getFirst()); diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/util/CommonSourceRootDetectionUtil.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/util/CommonSourceRootDetectionUtil.java index 23a936bea6f5..92dd7bb795f8 100644 --- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/util/CommonSourceRootDetectionUtil.java +++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/util/CommonSourceRootDetectionUtil.java @@ -21,7 +21,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.NullableFunction; -import com.intellij.util.text.CharArrayCharSequence; +import com.intellij.util.text.StringFactory; import org.jetbrains.annotations.Nullable; import java.io.File; @@ -98,7 +98,7 @@ public abstract class CommonSourceRootDetectionUtil<F> { @Override protected CharSequence loadText(final File file) throws IOException { - return new CharArrayCharSequence(FileUtil.loadFileText(file)); + return StringFactory.createShared(FileUtil.loadFileText(file)); } @Override diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java index b2ea31a2ec9d..cf7b201c0a70 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java @@ -39,6 +39,7 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.packaging.artifacts.Artifact; @@ -447,7 +448,7 @@ public class ArtifactEditorImpl implements ArtifactEditorEx { String oldFileName = ArtifactUtil.suggestArtifactFileName(oldArtifactName); final String name = ((ArchivePackagingElement)root).getArchiveFileName(); final String fileName = FileUtil.getNameWithoutExtension(name); - final String extension = FileUtil.getExtension(name); + final String extension = FileUtilRt.getExtension(name); if (fileName.equals(oldFileName) && extension.length() > 0) { myLayoutTreeComponent.editLayout(new Runnable() { @Override diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelActionBase.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelActionBase.java index c8f8b9719f69..e52cbd419d80 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelActionBase.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelActionBase.java @@ -37,8 +37,11 @@ import com.intellij.openapi.roots.ui.configuration.libraryEditor.ChangeLibraryLe import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.*; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.PathUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -125,7 +128,7 @@ public abstract class ChangeLibraryLevelActionBase extends AnAction { for (final File from : filesToProcess) { indicator.checkCanceled(); final File to = FileUtil.findSequentNonexistentFile(targetDir, FileUtil.getNameWithoutExtension(from), - FileUtil.getExtension(from.getName())); + FileUtilRt.getExtension(from.getName())); try { if (from.isDirectory()) { if (myCopy) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java index 0ba8d7d38b51..b5881c1d7768 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -879,7 +879,7 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple final DialogBuilder dialogBuilder = new DialogBuilder(myTree); dialogBuilder.setTitle(ProjectBundle.message("copy.module.dialog.title")); dialogBuilder.setCenterPanel(component); - dialogBuilder.setPreferedFocusComponent(component.getNameComponent()); + dialogBuilder.setPreferredFocusComponent(component.getNameComponent()); dialogBuilder.setOkOperation(new Runnable() { @Override public void run() { diff --git a/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java b/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java index 4e04baeee40d..d14db955f555 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java +++ b/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java @@ -16,6 +16,7 @@ package com.intellij.platform.templates; import com.intellij.ide.util.projectWizard.ModuleBuilder; +import com.intellij.ide.util.projectWizard.WizardInputField; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.ui.ValidationInfo; import com.intellij.platform.ProjectTemplate; @@ -23,6 +24,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.util.List; import java.util.zip.ZipInputStream; /** @@ -48,9 +50,11 @@ public abstract class ArchivedProjectTemplate implements ProjectTemplate { @NotNull @Override public ModuleBuilder createModuleBuilder() { - return new TemplateModuleBuilder(this, getModuleType()); + return new TemplateModuleBuilder(this, getModuleType(), getInputFields()); } + public abstract List<WizardInputField> getInputFields(); + @Nullable @Override public ValidationInfo validateSettings() { diff --git a/java/idea-ui/src/com/intellij/platform/templates/IC_templates.xml b/java/idea-ui/src/com/intellij/platform/templates/IC_templates.xml index 8da6b26f055a..d8daaec7b869 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/IC_templates.xml +++ b/java/idea-ui/src/com/intellij/platform/templates/IC_templates.xml @@ -1,8 +1,7 @@ <templates> <template> <name>Java Hello World</name> - <description><![CDATA[ Simple Java "Hello World" application. ]]> - </description> + <description><![CDATA[ Simple Java "Hello World" application. ]]></description> <path>HelloWorld.zip</path> </template> </templates> diff --git a/java/idea-ui/src/com/intellij/platform/templates/IU_template_groups.xml b/java/idea-ui/src/com/intellij/platform/templates/IU_template_groups.xml new file mode 100644 index 000000000000..92725d311e4a --- /dev/null +++ b/java/idea-ui/src/com/intellij/platform/templates/IU_template_groups.xml @@ -0,0 +1,24 @@ +<template-groups xmlns="http://www.jetbrains.com/projectTemplates"> + <group> + <name>Java Samples</name> + <path>Java</path> + <template> + <name>Java Hello World</name> + <description><![CDATA[ Simple Java "Hello World" application. ]]></description> + <path>HelloWorld.zip</path> + </template> + </group> + + <group> + <name>Spring</name> + <path>Spring</path> + <requiredPlugin>com.intellij.spring</requiredPlugin> + <requiredPlugin>org.jetbrains.idea.maven</requiredPlugin> + <template> + <name>Spring Core</name> + <description><![CDATA[ A simple console application with Spring Framework 3.2. ]]></description> + <path>SpringApp</path> + <input-field>IJ_BASE_PACKAGE</input-field> + </template> + </group> +</template-groups>
\ No newline at end of file diff --git a/java/idea-ui/src/com/intellij/platform/templates/IU_template_groups.xsd b/java/idea-ui/src/com/intellij/platform/templates/IU_template_groups.xsd new file mode 100644 index 000000000000..19d59f6c716d --- /dev/null +++ b/java/idea-ui/src/com/intellij/platform/templates/IU_template_groups.xsd @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" + targetNamespace="http://www.jetbrains.com/projectTemplates"> + <xs:element name="template-groups" type="template-groupsType"/> + <xs:complexType name="groupType"> + <xs:sequence> + <xs:element type="xs:string" name="name" minOccurs="1" maxOccurs="1"/> + <xs:element type="xs:string" name="path" minOccurs="1" maxOccurs="1"/> + <xs:element type="xs:string" name="requiredPlugin" minOccurs="0" maxOccurs="unbounded"/> + <xs:element type="templateType" name="template"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="templateType"> + <xs:sequence> + <xs:element type="xs:string" name="name" minOccurs="1" maxOccurs="1"/> + <xs:element type="xs:string" name="description" minOccurs="1" maxOccurs="1"/> + <xs:element type="xs:string" name="path" minOccurs="1" maxOccurs="1"/> + <xs:element type="xs:string" name="requiredPlugin" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="input-field" maxOccurs="unbounded" minOccurs="0"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="IJ_BASE_PACKAGE"/> + <xs:enumeration value="IJ_APPLICATION_SERVER"/> + </xs:restriction> + </xs:simpleType> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="template-groupsType"> + <xs:sequence> + <xs:element type="groupType" name="group"/> + </xs:sequence> + </xs:complexType> +</xs:schema>
\ No newline at end of file diff --git a/java/idea-ui/src/com/intellij/platform/templates/LocalArchivedTemplate.java b/java/idea-ui/src/com/intellij/platform/templates/LocalArchivedTemplate.java index 76c70ed4b1d5..1a8a152fcd30 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/LocalArchivedTemplate.java +++ b/java/idea-ui/src/com/intellij/platform/templates/LocalArchivedTemplate.java @@ -15,6 +15,7 @@ */ package com.intellij.platform.templates; +import com.intellij.ide.util.projectWizard.WizardInputField; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.module.ModuleTypeManager; @@ -22,11 +23,14 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.io.StreamUtil; import org.jdom.Document; +import org.jdom.Namespace; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.net.URL; +import java.util.Collections; +import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -37,9 +41,11 @@ import java.util.zip.ZipInputStream; public class LocalArchivedTemplate extends ArchivedProjectTemplate { static final String DESCRIPTION_PATH = ".idea/description.html"; + static final String IDEA_INPUT_FIELDS_XML = ".idea/input-fields.xml"; private final URL myArchivePath; private final ModuleType myModuleType; + private List<WizardInputField> myInputFields = Collections.emptyList(); public LocalArchivedTemplate(String displayName, URL archivePath) { @@ -47,6 +53,20 @@ public class LocalArchivedTemplate extends ArchivedProjectTemplate { myArchivePath = archivePath; myModuleType = computeModuleType(this); + String s = readEntry(new Condition<ZipEntry>() { + @Override + public boolean value(ZipEntry entry) { + return entry.getName().endsWith(IDEA_INPUT_FIELDS_XML); + } + }); + if (s != null) { + try { + myInputFields = RemoteTemplatesFactory.getFields(JDOMUtil.loadDocument(s).getRootElement(), Namespace.NO_NAMESPACE); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } } @Override @@ -105,6 +125,11 @@ public class LocalArchivedTemplate extends ArchivedProjectTemplate { } @Override + public List<WizardInputField> getInputFields() { + return myInputFields; + } + + @Override public ZipInputStream getStream() throws IOException { return new ZipInputStream(myArchivePath.openStream()); } diff --git a/java/idea-ui/src/com/intellij/platform/templates/RemoteTemplatesFactory.java b/java/idea-ui/src/com/intellij/platform/templates/RemoteTemplatesFactory.java index 33b6d84e594c..c5a3eef95a33 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/RemoteTemplatesFactory.java +++ b/java/idea-ui/src/com/intellij/platform/templates/RemoteTemplatesFactory.java @@ -17,26 +17,33 @@ package com.intellij.platform.templates; import com.intellij.ide.plugins.PluginManager; import com.intellij.ide.util.projectWizard.WizardContext; +import com.intellij.ide.util.projectWizard.WizardInputField; import com.intellij.openapi.application.ApplicationInfo; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.module.ModuleTypeManager; +import com.intellij.openapi.util.ClearableLazyValue; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.io.StreamUtil; import com.intellij.platform.ProjectTemplate; import com.intellij.platform.ProjectTemplatesFactory; +import com.intellij.util.ArrayUtil; +import com.intellij.util.Function; import com.intellij.util.NullableFunction; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.MultiMap; import com.intellij.util.net.HttpConfigurable; import org.jdom.Element; import org.jdom.JDOMException; +import org.jdom.Namespace; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; +import java.util.Collection; import java.util.List; import java.util.zip.ZipInputStream; @@ -47,32 +54,52 @@ import java.util.zip.ZipInputStream; public class RemoteTemplatesFactory extends ProjectTemplatesFactory { private static final String URL = "http://download.jetbrains.com/idea/project_templates/"; + public static final String SAMPLES_GALLERY = "Samples Gallery"; + private static final Namespace NAMESPACE = Namespace.getNamespace("http://www.jetbrains.com/projectTemplates"); + + public static final String INPUT_FIELD = "input-field"; + public static final String TEMPLATE = "template"; + public static final String INPUT_DEFAULT = "default"; + + private final ClearableLazyValue<MultiMap<String, ArchivedProjectTemplate>> myTemplates = new ClearableLazyValue<MultiMap<String, ArchivedProjectTemplate>>() { + @NotNull + @Override + protected MultiMap<String, ArchivedProjectTemplate> compute() { + return getTemplates(); + } + }; @NotNull @Override public String[] getGroups() { - return new String[] { "Samples Gallery"}; + myTemplates.drop(); + return ArrayUtil.toStringArray(myTemplates.getValue().keySet()); } @NotNull @Override public ProjectTemplate[] createTemplates(String group, WizardContext context) { + Collection<ArchivedProjectTemplate> templates = myTemplates.getValue().get(group); + return templates.toArray(new ProjectTemplate[templates.size()]); + } + + private static MultiMap<String, ArchivedProjectTemplate> getTemplates() { InputStream stream = null; HttpURLConnection connection = null; String code = ApplicationInfo.getInstance().getBuild().getProductCode(); try { connection = getConnection(code + "_templates.xml"); stream = connection.getInputStream(); - String text = StreamUtil.readText(stream); + String text = StreamUtil.readText(stream, TemplateModuleBuilder.UTF_8); return createFromText(text); } catch (IOException ex) { // timeouts, lost connection etc LOG.info(ex); - return ProjectTemplate.EMPTY_ARRAY; + return MultiMap.emptyInstance(); } catch (Exception e) { LOG.error(e); - return ProjectTemplate.EMPTY_ARRAY; + return MultiMap.emptyInstance(); } finally { StreamUtil.closeStream(stream); @@ -83,32 +110,53 @@ public class RemoteTemplatesFactory extends ProjectTemplatesFactory { } @SuppressWarnings("unchecked") - public static ProjectTemplate[] createFromText(String text) throws IOException, JDOMException { + public static MultiMap<String, ArchivedProjectTemplate> createFromText(String text) throws IOException, JDOMException { + + Element rootElement = JDOMUtil.loadDocument(text).getRootElement(); + List<Element> groups = rootElement.getChildren("group", NAMESPACE); + MultiMap<String, ArchivedProjectTemplate> map = new MultiMap<String, ArchivedProjectTemplate>(); + if (groups.isEmpty()) { // sample gallery by default + map.put(SAMPLES_GALLERY, createGroupTemplates(rootElement, Namespace.NO_NAMESPACE)); + } + else { + for (Element group : groups) { + if (checkRequiredPlugins(group, NAMESPACE)) { + map.put(group.getChildText("name", NAMESPACE), createGroupTemplates(group, NAMESPACE)); + } + } + } + + return map; + } - List<Element> elements = JDOMUtil.loadDocument(text).getRootElement().getChildren("template"); + @SuppressWarnings("unchecked") + private static List<ArchivedProjectTemplate> createGroupTemplates(Element groupElement, final Namespace ns) { + List<Element> elements = groupElement.getChildren(TEMPLATE, ns); - List<ProjectTemplate> templates = ContainerUtil.mapNotNull(elements, new NullableFunction<Element, ProjectTemplate>() { + return ContainerUtil.mapNotNull(elements, new NullableFunction<Element, ArchivedProjectTemplate>() { @Override - public ProjectTemplate fun(final Element element) { + public ArchivedProjectTemplate fun(final Element element) { - List<Element> plugins = element.getChildren("requiredPlugin"); - for (Element plugin : plugins) { - String id = plugin.getTextTrim(); - if (!PluginManager.isPluginInstalled(PluginId.getId(id))) { - return null; - } - } + if (!checkRequiredPlugins(element, ns)) return null; String type = element.getChildText("moduleType"); + final ModuleType moduleType = ModuleTypeManager.getInstance().findByID(type); - return new ArchivedProjectTemplate(element.getChildTextTrim("name")) { + + final List<WizardInputField> inputFields = getFields(element, ns); + return new ArchivedProjectTemplate(element.getChildTextTrim("name", ns)) { @Override protected ModuleType getModuleType() { return moduleType; } @Override + public List<WizardInputField> getInputFields() { + return inputFields; + } + + @Override public ZipInputStream getStream() throws IOException { - String path = element.getChildText("path"); + String path = element.getChildText("path", ns); final HttpURLConnection connection = getConnection(path); return new ZipInputStream(connection.getInputStream()) { @Override @@ -122,12 +170,32 @@ public class RemoteTemplatesFactory extends ProjectTemplatesFactory { @Nullable @Override public String getDescription() { - return element.getChildTextTrim("description"); + return element.getChildTextTrim("description", ns); } }; } }); - return templates.toArray(new ProjectTemplate[templates.size()]); + } + + static List<WizardInputField> getFields(Element templateElement, final Namespace ns) { + //noinspection unchecked + return ContainerUtil.map(templateElement.getChildren(INPUT_FIELD, ns), new Function<Element, WizardInputField>() { + @Override + public WizardInputField fun(Element element) { + return WizardInputField.getFieldById(element.getText(), element.getAttributeValue(INPUT_DEFAULT)); + } + }); + } + + private static boolean checkRequiredPlugins(Element element, Namespace ns) { + @SuppressWarnings("unchecked") List<Element> plugins = element.getChildren("requiredPlugin", ns); + for (Element plugin : plugins) { + String id = plugin.getTextTrim(); + if (!PluginManager.isPluginInstalled(PluginId.getId(id))) { + return false; + } + } + return true; } private static HttpURLConnection getConnection(String path) throws IOException { diff --git a/java/idea-ui/src/com/intellij/platform/templates/SaveProjectAsTemplateAction.java b/java/idea-ui/src/com/intellij/platform/templates/SaveProjectAsTemplateAction.java index f8d89ac83b23..c873488d406e 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/SaveProjectAsTemplateAction.java +++ b/java/idea-ui/src/com/intellij/platform/templates/SaveProjectAsTemplateAction.java @@ -16,11 +16,16 @@ package com.intellij.platform.templates; import com.intellij.CommonBundle; +import com.intellij.codeInspection.defaultFileTemplateUsage.FileHeaderChecker; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.util.projectWizard.ProjectTemplateParameterFactory; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.StorageScheme; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.progress.PerformInBackgroundOption; import com.intellij.openapi.progress.ProgressIndicator; @@ -33,6 +38,7 @@ import com.intellij.openapi.roots.FileIndex; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.StreamUtil; import com.intellij.openapi.vfs.VfsUtil; @@ -40,12 +46,16 @@ import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.io.ZipUtil; import com.intellij.util.ui.UIUtil; +import gnu.trove.TIntObjectHashMap; +import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; +import java.io.*; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -80,7 +90,7 @@ public class SaveProjectAsTemplateAction extends AnAction { ProgressManager.getInstance().run(new Task.Backgroundable(project, "Saving Project as Template", true, PerformInBackgroundOption.DEAF) { @Override public void run(@NotNull final ProgressIndicator indicator) { - saveProject(project, file, moduleToSave, description, indicator); + saveProject(project, file, moduleToSave, description, dialog.isReplaceParameters(), indicator); } @Override @@ -102,11 +112,26 @@ public class SaveProjectAsTemplateAction extends AnAction { } public static void saveProject(final Project project, - final File zipFile, - Module moduleToSave, - final String description, - final ProgressIndicator indicator) { + final File zipFile, + Module moduleToSave, + final String description, + boolean replaceParameters, + final ProgressIndicator indicator) { + final Map<String, String> parameters = new HashMap<String, String>(); + if (replaceParameters) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + ProjectTemplateParameterFactory[] extensions = Extensions.getExtensions(ProjectTemplateParameterFactory.EP_NAME); + for (ProjectTemplateParameterFactory extension : extensions) { + String value = extension.detectParameterValue(project); + if (value != null) { + parameters.put(value, extension.getParameterId()); + } + } + } + }); + } indicator.setText("Saving project..."); UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override @@ -143,30 +168,62 @@ public class SaveProjectAsTemplateAction extends AnAction { } }); } + if (replaceParameters) { + String text = getInputFieldsText(parameters); + stream.putNextEntry(new ZipEntry(dir.getName() + "/" + LocalArchivedTemplate.IDEA_INPUT_FIELDS_XML)); + stream.write(text.getBytes()); + stream.closeEntry(); + } FileIndex index = moduleToSave == null ? ProjectRootManager.getInstance(project).getFileIndex() : ModuleRootManager.getInstance(moduleToSave).getFileIndex(); final ZipOutputStream finalStream = stream; + + final FileTemplate template = FileTemplateManager.getInstance().getDefaultTemplate(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME); + final String templateText = template.getText(); + final Pattern pattern = FileHeaderChecker.getTemplatePattern(template, project, new TIntObjectHashMap<String>()); + index.iterateContent(new ContentIterator() { @Override - public boolean processFile(VirtualFile file) { - if (!file.isDirectory()) { - indicator.setText2(file.getName()); + public boolean processFile(final VirtualFile virtualFile) { + if (!virtualFile.isDirectory()) { + String name = virtualFile.getName(); + indicator.setText2(name); try { - String relativePath = VfsUtilCore.getRelativePath(file, dir, '/'); + String relativePath = VfsUtilCore.getRelativePath(virtualFile, dir, '/'); if (relativePath == null) { - throw new RuntimeException("Can't find relative path for " + file); + throw new RuntimeException("Can't find relative path for " + virtualFile); + } + boolean system = ".idea".equals(virtualFile.getParent().getName()); + if (system) { + if (!name.equals("description.html") && + !name.equals("misc.xml") && + !name.equals("modules.xml") && + !name.equals("workspace.xml")) { + return true; + } } - ZipUtil.addFileToZip(finalStream, new File(file.getPath()), dir.getName() + "/" + relativePath, null, null); + + ZipUtil.addFileToZip(finalStream, new File(virtualFile.getPath()), dir.getName() + "/" + relativePath, null, null, new ZipUtil.FileContentProcessor() { + @Override + public InputStream getContent(File file) throws IOException { + if (virtualFile.getFileType().isBinary()) return STANDARD.getContent(file); + + String s = VfsUtilCore.loadText(virtualFile); + String result = convertTemplates(s, pattern, templateText); + for (Map.Entry<String, String> entry : parameters.entrySet()) { + result = result.replace(entry.getKey(), "${" + entry.getValue() + "}"); + } + return new ByteArrayInputStream(result.getBytes(TemplateModuleBuilder.UTF_8)); + } + }); } catch (IOException e) { - throw new RuntimeException(e); + LOG.error(e); } } indicator.checkCanceled(); - // if (!".idea".equals(fileName.getParent())) return true; - // todo filter out some garbage from .idea return true; } }); @@ -195,6 +252,37 @@ public class SaveProjectAsTemplateAction extends AnAction { } } + public static String convertTemplates(String input, Pattern pattern, String template) { + Matcher matcher = pattern.matcher(input); + int start = matcher.matches() ? matcher.start(1) : -1; + StringBuilder builder = new StringBuilder(input.length() + 10); + for (int i = 0; i < input.length(); i++) { + if (start == i) { + builder.append(template); + //noinspection AssignmentToForLoopParameter + i = matcher.end(1); + } + + char c = input.charAt(i); + if (c == '$' || c == '#') { + builder.append('\\'); + } + builder.append(c); + } + return builder.toString(); + } + + private static String getInputFieldsText(Map<String, String> parameters) { + Element element = new Element(RemoteTemplatesFactory.TEMPLATE); + for (Map.Entry<String, String> entry : parameters.entrySet()) { + Element field = new Element(RemoteTemplatesFactory.INPUT_FIELD); + field.setText(entry.getValue()); + field.setAttribute(RemoteTemplatesFactory.INPUT_DEFAULT, entry.getKey()); + element.addContent(field); + } + return JDOMUtil.writeElement(element); + } + @Override public void update(AnActionEvent e) { Project project = getEventProject(e); diff --git a/java/idea-ui/src/com/intellij/platform/templates/SaveProjectAsTemplateDialog.form b/java/idea-ui/src/com/intellij/platform/templates/SaveProjectAsTemplateDialog.form index ebcd02909d82..725b1a923109 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/SaveProjectAsTemplateDialog.form +++ b/java/idea-ui/src/com/intellij/platform/templates/SaveProjectAsTemplateDialog.form @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.platform.templates.SaveProjectAsTemplateDialog"> - <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <xy x="20" y="20" width="370" height="170"/> + <xy x="20" y="20" width="372" height="170"/> </constraints> <properties/> <border type="none"/> @@ -60,6 +60,15 @@ <text value="&Save:"/> </properties> </component> + <component id="c6f1f" class="com.intellij.ui.components.JBCheckBox" binding="myReplaceParameters"> + <constraints> + <grid row="4" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <selected value="true"/> + <text value="&Replace parameters with placeholders"/> + </properties> + </component> </children> </grid> </form> diff --git a/java/idea-ui/src/com/intellij/platform/templates/SaveProjectAsTemplateDialog.java b/java/idea-ui/src/com/intellij/platform/templates/SaveProjectAsTemplateDialog.java index 860c54f325e1..dd539427062c 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/SaveProjectAsTemplateDialog.java +++ b/java/idea-ui/src/com/intellij/platform/templates/SaveProjectAsTemplateDialog.java @@ -21,12 +21,15 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.ValidationInfo; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.CollectionComboBoxModel; import com.intellij.ui.EditorTextField; +import com.intellij.ui.components.JBCheckBox; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -51,12 +54,15 @@ public class SaveProjectAsTemplateDialog extends DialogWrapper { private EditorTextField myDescription; private JComboBox myModuleCombo; private JLabel myModuleLabel; + private JBCheckBox myReplaceParameters; protected SaveProjectAsTemplateDialog(@NotNull Project project, @Nullable VirtualFile descriptionFile) { super(project); myProject = project; setTitle("Save Project As Template"); + myName.setText(project.getName()); + Module[] modules = ModuleManager.getInstance(project).getModules(); if (modules.length < 2) { myModuleLabel.setVisible(false); @@ -109,8 +115,22 @@ public class SaveProjectAsTemplateDialog extends DialogWrapper { if (StringUtil.isEmpty(myName.getText())) { return new ValidationInfo("Template name should not be empty"); } + return null; + } + + @Override + protected void doOKAction() { File file = getTemplateFile(); - return file.exists() ? new ValidationInfo("Template already exists") : null; + if (file.exists()) { + if (Messages.showYesNoDialog(myPanel, + FileUtil.getNameWithoutExtension(file) + " exists already.\n" + + "Do you want to replace it with the new one?", "Template Already Exists", + Messages.getWarningIcon()) == Messages.NO) { + return; + } + file.delete(); + } + super.doOKAction(); } File getTemplateFile() { @@ -122,6 +142,10 @@ public class SaveProjectAsTemplateDialog extends DialogWrapper { return myDescription.getText(); } + boolean isReplaceParameters() { + return myReplaceParameters.isSelected(); + } + @Nullable Module getModuleToSave() { String item = (String)myModuleCombo.getSelectedItem(); diff --git a/java/idea-ui/src/com/intellij/platform/templates/TemplateModuleBuilder.java b/java/idea-ui/src/com/intellij/platform/templates/TemplateModuleBuilder.java index 852989758e12..a18236209d11 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/TemplateModuleBuilder.java +++ b/java/idea-ui/src/com/intellij/platform/templates/TemplateModuleBuilder.java @@ -18,12 +18,14 @@ package com.intellij.platform.templates; import com.intellij.execution.RunManager; import com.intellij.execution.configurations.ModuleBasedConfiguration; import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.fileTemplates.FileTemplateUtil; import com.intellij.ide.util.newProjectWizard.modes.ImportImlMode; -import com.intellij.ide.util.projectWizard.ModuleBuilder; -import com.intellij.ide.util.projectWizard.ModuleWizardStep; -import com.intellij.ide.util.projectWizard.WizardContext; +import com.intellij.ide.util.projectWizard.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.module.*; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.progress.ProgressManager; @@ -31,9 +33,11 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.NullableComputable; +import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.io.StreamUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; @@ -47,6 +51,8 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; +import java.util.List; +import java.util.Properties; import java.util.zip.ZipInputStream; /** @@ -55,21 +61,17 @@ import java.util.zip.ZipInputStream; */ public class TemplateModuleBuilder extends ModuleBuilder { - private static final NullableFunction<String,String> PATH_CONVERTOR = new NullableFunction<String, String>() { - @Nullable - @Override - public String fun(String s) { - return s.contains(".idea") ? null : s; - } - }; + public static final String UTF_8 = "UTF-8"; private final ModuleType myType; + private List<WizardInputField> myAdditionalFields; private ArchivedProjectTemplate myTemplate; private boolean myProjectMode; - public TemplateModuleBuilder(ArchivedProjectTemplate template, ModuleType moduleType) { + public TemplateModuleBuilder(ArchivedProjectTemplate template, ModuleType moduleType, List<WizardInputField> additionalFields) { myTemplate = template; myType = moduleType; + myAdditionalFields = additionalFields; } @Override @@ -83,6 +85,11 @@ public class TemplateModuleBuilder extends ModuleBuilder { } @Override + protected List<WizardInputField> getAdditionalFields() { + return myAdditionalFields; + } + + @Override public Module commitModule(@NotNull final Project project, ModifiableModuleModel model) { if (myProjectMode) { final Module[] modules = ModuleManager.getInstance(project).getModules(); @@ -93,17 +100,30 @@ public class TemplateModuleBuilder extends ModuleBuilder { public void run() { try { setupModule(module); - ModifiableModuleModel modifiableModuleModel = ModuleManager.getInstance(project).getModifiableModel(); - modifiableModuleModel.renameModule(module, module.getProject().getName()); - modifiableModuleModel.commit(); - fixModuleName(module); } catch (ConfigurationException e) { LOG.error(e); } - catch (ModuleWithNameAlreadyExists exists) { - // do nothing - } + } + }); + + StartupManager.getInstance(project).registerPostStartupActivity(new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + try { + ModifiableModuleModel modifiableModuleModel = ModuleManager.getInstance(project).getModifiableModel(); + modifiableModuleModel.renameModule(module, module.getProject().getName()); + modifiableModuleModel.commit(); + fixModuleName(module); + } + catch (ModuleWithNameAlreadyExists exists) { + // do nothing + } + } + }); } }); return module; @@ -143,12 +163,39 @@ public class TemplateModuleBuilder extends ModuleBuilder { } } - private void unzip(String path, boolean moduleMode) { + private WizardInputField getBasePackageField() { + for (WizardInputField field : getAdditionalFields()) { + if (ProjectTemplateParameterFactory.IJ_BASE_PACKAGE.equals(field.getId())) { + return field; + } + } + return null; + } + + private void unzip(String path, final boolean moduleMode) { File dir = new File(path); ZipInputStream zipInputStream = null; + final WizardInputField basePackage = getBasePackageField(); try { zipInputStream = myTemplate.getStream(); - ZipUtil.unzip(ProgressManager.getInstance().getProgressIndicator(), dir, zipInputStream, moduleMode ? PATH_CONVERTOR : null); + NullableFunction<String, String> pathConvertor = new NullableFunction<String, String>() { + @Nullable + @Override + public String fun(String path) { + if (moduleMode && path.contains(".idea")) return null; + if (basePackage != null) { + return path.replace(getPathFragment(basePackage.getDefaultValue()), getPathFragment(basePackage.getValue())); + } + return path; + } + }; + ZipUtil.unzip(ProgressManager.getInstance().getProgressIndicator(), dir, zipInputStream, pathConvertor, new ZipUtil.ContentProcessor() { + @Override + public byte[] processContent(byte[] content, String fileName) throws IOException { + FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension(FileUtilRt.getExtension(fileName)); + return fileType.isBinary() ? content : processTemplates(new String(content)); + } + }); String iml = ContainerUtil.find(dir.list(), new Condition<String>() { @Override public boolean value(String s) { @@ -176,6 +223,19 @@ public class TemplateModuleBuilder extends ModuleBuilder { } } + private static String getPathFragment(String value) { + return "/" + value.replace('.', '/') + "/"; + } + + private byte[] processTemplates(String s) throws IOException { + Properties properties = FileTemplateManager.getInstance().getDefaultProperties(); + for (WizardInputField field : myAdditionalFields) { + properties.putAll(field.getValues()); + } + String merged = FileTemplateUtil.mergeTemplate(properties, s, true); + return merged.replace("\\$", "$").replace("\\#", "#").getBytes(UTF_8); + } + @Nullable @Override public Project createProject(String name, final String path) { diff --git a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java index 331db279750b..1a394ba51b5d 100644 --- a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java +++ b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java @@ -19,6 +19,7 @@ package com.intellij.util.descriptors.impl; import com.intellij.openapi.Disposable; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.ModificationTracker; import com.intellij.openapi.util.MultiValuesMap; import com.intellij.openapi.vfs.*; import com.intellij.util.EventDispatcher; @@ -40,6 +41,7 @@ public class ConfigFileContainerImpl implements ConfigFileContainer { private ConfigFile[] myCachedConfigFiles; private final ConfigFileMetaDataProvider myMetaDataProvider; private final ConfigFileInfoSetImpl myConfiguration; + private long myModificationCount; public ConfigFileContainerImpl(final Project project, final ConfigFileMetaDataProvider descriptorMetaDataProvider, final ConfigFileInfoSetImpl configuration) { @@ -58,6 +60,15 @@ public class ConfigFileContainerImpl implements ConfigFileContainer { myConfiguration.setContainer(this); } + public void incModificationCount() { + myModificationCount ++; + } + + @Override + public long getModificationCount() { + return myModificationCount; + } + private void fileChanged(final VirtualFile file) { for (ConfigFile descriptor : myConfigFiles.values()) { final VirtualFile virtualFile = descriptor.getVirtualFile(); @@ -94,6 +105,7 @@ public class ConfigFileContainerImpl implements ConfigFileContainer { } public void fireDescriptorChanged(final ConfigFile descriptor) { + incModificationCount(); myDispatcher.getMulticaster().configFileChanged(descriptor); } @@ -149,9 +161,11 @@ public class ConfigFileContainerImpl implements ConfigFileContainer { myCachedConfigFiles = null; for (ConfigFile configFile : added) { + incModificationCount(); myDispatcher.getMulticaster().configFileAdded(configFile); } for (ConfigFile configFile : toDelete) { + incModificationCount(); myDispatcher.getMulticaster().configFileRemoved(configFile); } } diff --git a/java/java-impl/src/com/intellij/application/options/ImportLayoutPanel.java b/java/java-impl/src/com/intellij/application/options/ImportLayoutPanel.java index ae7ffba1749b..d82d51f56b6e 100644 --- a/java/java-impl/src/com/intellij/application/options/ImportLayoutPanel.java +++ b/java/java-impl/src/com/intellij/application/options/ImportLayoutPanel.java @@ -15,6 +15,7 @@ */ package com.intellij.application.options; +import com.intellij.ide.highlighter.JavaHighlightingColors; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.editor.SyntaxHighlighterColors; @@ -330,7 +331,7 @@ public abstract class ImportLayoutPanel extends JPanel { append(" <blank line>", SimpleTextAttributes.LINK_ATTRIBUTES); } else { - TextAttributes attributes = SyntaxHighlighterColors.KEYWORD.getDefaultAttributes(); + TextAttributes attributes = JavaHighlightingColors.KEYWORD.getDefaultAttributes(); append("import", SimpleTextAttributes.fromTextAttributes(attributes)); if (entry.isStatic()) { append(" ", SimpleTextAttributes.REGULAR_ATTRIBUTES); diff --git a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java index fc2547da6aa1..2fbd2e903e16 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java @@ -22,6 +22,7 @@ import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; import com.intellij.ide.highlighter.XmlFileType; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.CommandProcessor; @@ -54,6 +55,7 @@ import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.PopupStep; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; @@ -64,9 +66,11 @@ import com.intellij.psi.xml.XmlDocument; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.util.*; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.OptionsMessageDialog; +import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -77,6 +81,7 @@ import java.awt.event.ActionEvent; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Set; /** * @author anna @@ -144,16 +149,17 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM chooseRootAndAnnotateExternally(listOwner, annotationFQName, fromFile, project, packageName, roots, value); } else { - if (ApplicationManager.getApplication().isUnitTestMode() || ApplicationManager.getApplication().isHeadlessEnvironment()) { + Application application = ApplicationManager.getApplication(); + if (application.isUnitTestMode() || application.isHeadlessEnvironment()) { notifyAfterAnnotationChanging(listOwner, annotationFQName, false); return; } - SwingUtilities.invokeLater(new Runnable() { + application.invokeLater(new Runnable() { @Override public void run() { setupRootAndAnnotateExternally(entry, project, listOwner, annotationFQName, fromFile, packageName, value); } - }); + }, project.getDisposed()); } break; } @@ -204,12 +210,8 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM else { final XmlFile annotationsXml = createAnnotationsXml(newRoot, packageName); if (annotationsXml != null) { - final List<PsiFile> createdFiles = new ArrayList<PsiFile>(); - createdFiles.add(annotationsXml); - String fqn = getFQN(packageName, fromFile); - if (fqn != null) { - myExternalAnnotations.put(fqn, createdFiles); - } + List<PsiFile> createdFiles = new SmartList<PsiFile>(annotationsXml); + cacheExternalAnnotations(packageName, fromFile, createdFiles); } annotateExternally(listOwner, annotationFQName, annotationsXml, fromFile, value); } @@ -271,12 +273,12 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM @NotNull private static VirtualFile[] filterByReadOnliness(@NotNull VirtualFile[] files) { - List<VirtualFile> result = new ArrayList<VirtualFile>(); - for (VirtualFile file : files) { - if (file.isInLocalFileSystem()) { - result.add(file); + List<VirtualFile> result = ContainerUtil.filter(files, new Condition<VirtualFile>() { + @Override + public boolean value(VirtualFile file) { + return file.isInLocalFileSystem(); } - } + }); return VfsUtilCore.toVirtualFileArray(result); } @@ -295,7 +297,7 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM return; } - final List<PsiFile> annotationFiles = xmlFiles == null ? new ArrayList<PsiFile>() : new ArrayList<PsiFile>(xmlFiles); + final Set<PsiFile> annotationFiles = xmlFiles == null ? new THashSet<PsiFile>() : new THashSet<PsiFile>(xmlFiles); new WriteCommandAction(project) { @Override @@ -310,7 +312,7 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM } else { annotationFiles.add(newXml); - myExternalAnnotations.put(getFQN(packageName, fromFile), annotationFiles); + cacheExternalAnnotations(packageName, fromFile, new SmartList<PsiFile>(annotationFiles)); annotateExternally(listOwner, annotationFQName, newXml, fromFile, value); } } @@ -507,7 +509,7 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM sdkModificator.addRoot(vFile, AnnotationOrderRootType.getInstance()); sdkModificator.commitChanges(); } - myExternalAnnotations.clear(); + dropCache(); } private void annotateExternally(@NotNull final PsiModifierListOwner listOwner, @@ -528,16 +530,17 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM final XmlTag rootTag = document.getRootTag(); final String externalName = getExternalName(listOwner, false); if (rootTag != null) { - for (XmlTag tag : rootTag.getSubTags()) { - if (Comparing.strEqual(StringUtil.unescapeXml(tag.getAttributeValue("name")), externalName)) { - for (XmlTag annTag : tag.getSubTags()) { - if (Comparing.strEqual(annTag.getAttributeValue("name"), annotationFQName)) { - annTag.delete(); + for (XmlTag item : rootTag.getSubTags()) { + if (Comparing.strEqual(StringUtil.unescapeXml(item.getAttributeValue("name")), externalName)) { + for (XmlTag annotation : item.getSubTags()) { + if (Comparing.strEqual(annotation.getAttributeValue("name"), annotationFQName)) { + annotation.delete(); break; } } - tag.add(XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText( - createAnnotationTag(annotationFQName, values))); + XmlTag newTag = XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText( + createAnnotationTag(annotationFQName, values)); + item.add(newTag); commitChanges(xmlFile); notifyAfterAnnotationChanging(listOwner, annotationFQName, true); return; diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java index 9abea2e942c2..a7ae91fd10f7 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java @@ -22,11 +22,13 @@ import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.infos.CandidateInfo; 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.Collection; +import java.util.Iterator; import java.util.List; /** @@ -221,6 +223,15 @@ public class ConstructorInsertHandler implements InsertHandler<LookupElementDeco if (aClass == null) return; final Collection<CandidateInfo> candidatesToImplement = OverrideImplementUtil.getMethodsToOverrideImplement(aClass, true); + if (PsiUtil.isLanguageLevel8OrHigher(aClass)) { + for (Iterator<CandidateInfo> iterator = candidatesToImplement.iterator(); iterator.hasNext(); ) { + final CandidateInfo candidate = iterator.next(); + final PsiElement element = candidate.getElement(); + if (element instanceof PsiMethod && ((PsiMethod)element).hasModifierProperty(PsiModifier.DEFAULT)) { + iterator.remove(); + } + } + } boolean invokeOverride = candidatesToImplement.isEmpty(); if (invokeOverride){ OverrideImplementUtil.chooseAndOverrideOrImplementMethods(project, editor, aClass, false); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java index be4867cc9c05..e84eb2646ec0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java @@ -66,7 +66,7 @@ public class JavaClassReferenceCompletionContributor extends CompletionContribut return; } - if (parameters.getCompletionType() == CompletionType.CLASS_NAME) { + if (parameters.isExtendedCompletion() || parameters.getCompletionType() == CompletionType.CLASS_NAME) { JavaClassNameCompletionContributor.addAllClasses(parameters, result); } else { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java index d29078b2658d..b264d0e2bd00 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java @@ -416,7 +416,7 @@ public class JavaCompletionData extends JavaAwareCompletionData { statement = PsiTreeUtil.getParentOfType(position, PsiDeclarationStatement.class); } if (statement != null && statement.getTextRange().getStartOffset() == position.getTextRange().getStartOffset()) { - if (!psiElement().withSuperParent(2, PsiSwitchStatement.class).accepts(statement)) { + if (!psiElement().withSuperParent(2, PsiSwitchStatement.class).afterLeaf("{").accepts(statement)) { result.addElement(new OverrideableSpace(createKeyword(position, PsiKeyword.FINAL), TailType.HUMBLE_SPACE_BEFORE_WORD)); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java index 61738b40f4d4..236e2e6768f6 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java @@ -59,10 +59,7 @@ public class JavaCompletionSorting { final boolean afterNew = JavaSmartCompletionContributor.AFTER_NEW.accepts(position); List<LookupElementWeigher> afterPriority = new ArrayList<LookupElementWeigher>(); - if (!smart) { - ContainerUtil.addIfNotNull(afterPriority, preferStatics(position, expectedTypes)); - } - else { + if (smart) { afterPriority.add(new PreferDefaultTypeWeigher(expectedTypes, parameters)); } ContainerUtil.addIfNotNull(afterPriority, recursion(parameters, expectedTypes)); @@ -83,13 +80,13 @@ public class JavaCompletionSorting { } List<LookupElementWeigher> afterPrefix = ContainerUtil.newArrayList(); - if (smart) { - afterPriority.add(new PreferByKindWeigher(type, position, true)); + if (!smart) { + ContainerUtil.addIfNotNull(afterPrefix, preferStatics(position, expectedTypes)); } if (!smart && !afterNew) { afterPrefix.add(new PreferExpected(false, expectedTypes)); } - afterPrefix.add(new PreferByKindWeigher(type, position, false)); + afterPrefix.add(new PreferByKindWeigher(type, position)); Collections.addAll(afterPrefix, new PreferNonGeneric(), new PreferAccessible(position), new PreferSimple(), new PreferEnumConstants(parameters)); @@ -107,7 +104,7 @@ public class JavaCompletionSorting { final PsiReferenceExpression reference = expression != null ? expression.getMethodExpression() : PsiTreeUtil.getParentOfType(position, PsiReferenceExpression.class); if (reference == null) return null; - return new RecursionWeigher(position, reference, expression, expectedInfos); + return new RecursionWeigher(position, parameters.getCompletionType(), reference, expression, expectedInfos); } @Nullable @@ -132,7 +129,9 @@ public class JavaCompletionSorting { public Comparable weigh(@NotNull LookupElement element) { final Object o = element.getObject(); if (o instanceof PsiKeyword) return -3; - if (!(o instanceof PsiMember)) return 0; + if (!(o instanceof PsiMember) || element.getUserData(JavaOverrideCompletionContributor.OVERRIDE_ELEMENT) != null) { + return 0; + } if (((PsiMember)o).hasModifierProperty(PsiModifier.STATIC) && !hasNonVoid(infos)) { if (o instanceof PsiMethod) return -5; @@ -405,7 +404,7 @@ public class JavaCompletionSorting { public Comparable weigh(@NotNull LookupElement element) { final PsiTypeLookupItem lookupItem = element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY); if (lookupItem != null) { - return lookupItem.getBracketsCount(); + return lookupItem.getBracketsCount() * 10 + (lookupItem.isAddArrayInitializer() ? 1 : 0); } if (element.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null) { return 239; diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java index 52d493b551dd..9904c46f560a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java @@ -50,6 +50,14 @@ public class JavaInheritorsGetter extends CompletionProvider<CompletionParameter myConstructorInsertHandler = constructorInsertHandler; } + private static boolean shouldAddArrayInitializer(PsiElement position) { + if (!JavaCompletionContributor.isInJavaContext(position) || !JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) { + return false; + } + PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(position, PsiNewExpression.class); + return newExpression != null && newExpression.getParent() instanceof PsiExpressionList; + } + @Override public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext matchingContext, @NotNull final CompletionResultSet result) { final ExpectedTypeInfo[] infos = JavaSmartCompletionContributor.getExpectedTypes(parameters); @@ -88,16 +96,26 @@ public class JavaInheritorsGetter extends CompletionProvider<CompletionParameter for (final PsiType type : ExpectedTypesGetter.extractTypes(infos, true)) { if (type instanceof PsiArrayType) { - final LookupItem item = PsiTypeLookupItem.createLookupItem(TypeConversionUtil.erasure(type), identifierCopy); - if (item.getObject() instanceof PsiClass) { - JavaCompletionUtil.setShowFQN(item); + consumer.consume(createNewArrayItem(identifierCopy, type)); + + if (shouldAddArrayInitializer(identifierCopy)) { + PsiTypeLookupItem item = createNewArrayItem(identifierCopy, type); + item.setAddArrayInitializer(); + consumer.consume(item); } - item.setInsertHandler(new DefaultInsertHandler()); //braces & shortening - consumer.consume(item); } } } + private static PsiTypeLookupItem createNewArrayItem(PsiElement identifierCopy, PsiType type) { + PsiTypeLookupItem item = PsiTypeLookupItem.createLookupItem(TypeConversionUtil.erasure(type), identifierCopy); + if (item.getObject() instanceof PsiClass) { + JavaCompletionUtil.setShowFQN(item); + } + item.setInsertHandler(new DefaultInsertHandler()); //braces & shortening + return item; + } + private static List<PsiClassType> extractClassTypes(ExpectedTypeInfo[] infos) { final List<PsiClassType> expectedClassTypes = new SmartList<PsiClassType>(); for (PsiType type : ExpectedTypesGetter.extractTypes(infos, true)) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaOverrideCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaOverrideCompletionContributor.java new file mode 100644 index 000000000000..d71de30567c2 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaOverrideCompletionContributor.java @@ -0,0 +1,123 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.completion; + +import com.intellij.codeInsight.generation.GenerateMembersUtil; +import com.intellij.codeInsight.generation.OverrideImplementExploreUtil; +import com.intellij.codeInsight.generation.OverrideImplementUtil; +import com.intellij.codeInsight.generation.PsiGenerationInfo; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.util.Key; +import com.intellij.psi.*; +import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiFormatUtilBase; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.ui.RowIcon; +import com.intellij.util.Consumer; + +import java.util.List; + +import static com.intellij.patterns.PlatformPatterns.psiElement; + +/** + * @author peter + */ +public class JavaOverrideCompletionContributor extends CompletionContributor { + static final Key<Boolean> OVERRIDE_ELEMENT = Key.create("OVERRIDE_ELEMENT"); + + @Override + public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet _result) { + if (parameters.getCompletionType() != CompletionType.BASIC && parameters.getCompletionType() != CompletionType.SMART) { + return; + } + + PsiElement position = parameters.getPosition(); + if (psiElement(PsiIdentifier.class).withParents(PsiJavaCodeReferenceElement.class, PsiTypeElement.class, PsiClass.class). + andNot(JavaCompletionData.AFTER_DOT). + andNot(psiElement().afterLeaf(psiElement().inside(PsiModifierList.class))).accepts(position)) { + final PsiClass parent = CompletionUtil.getOriginalElement((PsiClass)position.getParent().getParent().getParent()); + if (parent != null) { + CompletionResultSet result = JavaCompletionSorting.addJavaSorting(parameters, _result); + addSuperSignatureElements(parent, true, result); + addSuperSignatureElements(parent, false, result); + } + } + + } + + private static void addSuperSignatureElements(final PsiClass parent, boolean implemented, CompletionResultSet result) { + for (CandidateInfo candidate : OverrideImplementExploreUtil.getMethodsToOverrideImplement(parent, implemented)) { + PsiMethod baseMethod = (PsiMethod)candidate.getElement(); + if (!baseMethod.isConstructor()) { + PsiClass baseClass = baseMethod.getContainingClass(); + List<PsiMethod> prototypes = OverrideImplementUtil.overrideOrImplementMethod(parent, baseMethod, candidate.getSubstitutor(), new Consumer<PsiMethod>() { + @Override + public void consume(PsiMethod method) { + OverrideImplementUtil.deleteDocComment(method); + } + }); + if (!prototypes.isEmpty() && baseClass != null) { + result.addElement(createOverridingLookupElement(parent, implemented, baseMethod, baseClass, prototypes.get(0))); + } + } + } + } + + private static LookupElementBuilder createOverridingLookupElement(final PsiClass parent, + boolean implemented, + final PsiMethod baseMethod, + PsiClass baseClass, final PsiMethod prototype) { + PsiIdentifier nameIdentifier = prototype.getNameIdentifier(); + assert nameIdentifier != null; + + String signature = prototype.getModifierList().getText(); + if (!signature.isEmpty()) { + signature += " "; + } + PsiType returnType = prototype.getReturnType(); + signature += TypeConversionUtil.erasure(returnType).getPresentableText() + " " + prototype.getName(); + + String parameters = PsiFormatUtil.formatMethod(prototype, PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_PARAMETERS, PsiFormatUtilBase.SHOW_NAME); + + InsertHandler<LookupElement> insertHandler = new InsertHandler<LookupElement>() { + @Override + public void handleInsert(InsertionContext context, LookupElement item) { + context.getDocument().deleteString(context.getStartOffset(), context.getTailOffset()); + context.commitDocument(); + + List<PsiMethod> prototypes = OverrideImplementUtil.overrideOrImplementMethod(parent, baseMethod, false); + List<PsiGenerationInfo<PsiMethod>> infos = OverrideImplementUtil.convert2GenerationInfos(prototypes); + List<PsiGenerationInfo<PsiMethod>> newInfos = GenerateMembersUtil.insertMembersAtOffset(context.getFile(), context.getStartOffset(), infos); + if (!newInfos.isEmpty()) { + newInfos.get(0).positionCaret(context.getEditor(), true); + } + } + }; + + RowIcon icon = new RowIcon(2); + icon.setIcon(baseMethod.getIcon(0), 0); + icon.setIcon(implemented ? AllIcons.Gutter.ImplementingMethod : AllIcons.Gutter.OverridingMethod, 1); + + LookupElementBuilder element = LookupElementBuilder.create(baseMethod, signature).withLookupString(prototype.getName()). + withLookupString(signature).withInsertHandler(insertHandler). + appendTailText(parameters, false).appendTailText(" {...}", true).withTypeText(baseClass.getName()).withIcon(icon); + element.putUserData(OVERRIDE_ELEMENT, true); + return element; + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java index 62bef3f0c9ad..349cb7b47890 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java @@ -142,7 +142,9 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> { } public static void renderClassItem(LookupElementPresentation presentation, LookupItem item, PsiClass psiClass, boolean diamond) { - presentation.setIcon(DefaultLookupItemRenderer.getRawIcon(item, presentation.isReal())); + if (!(psiClass instanceof PsiTypeParameter)) { + presentation.setIcon(DefaultLookupItemRenderer.getRawIcon(item, presentation.isReal())); + } final boolean bold = item.getAttribute(LookupItem.HIGHLIGHTED_ATTR) != null; boolean strikeout = JavaElementLookupRenderer.isToStrikeout(item); @@ -153,9 +155,12 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> { String tailText = StringUtil.notNullize((String) item.getAttribute(LookupItem.TAIL_TEXT_ATTR)); PsiSubstitutor substitutor = (PsiSubstitutor)item.getAttribute(LookupItem.SUBSTITUTOR); - if (item instanceof PsiTypeLookupItem && ((PsiTypeLookupItem)item).isIndicateAnonymous() && - (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT))) { - tailText = "{...}" + tailText; + if (item instanceof PsiTypeLookupItem) { + if (((PsiTypeLookupItem)item).isIndicateAnonymous() && + (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) || + ((PsiTypeLookupItem)item).isAddArrayInitializer()) { + tailText = "{...}" + tailText; + } } if (substitutor == null && !diamond && psiClass.getTypeParameters().length > 0) { tailText = "<" + StringUtil.join(psiClass.getTypeParameters(), new Function<PsiTypeParameter, String>() { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java index 8ed82061134f..a3a44ad6d4aa 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java @@ -46,7 +46,8 @@ public class PreferByKindWeigher extends LookupElementWeigher { psiElement(PsiVariable.class).withParent(PsiCatchSection.class))))); static final ElementPattern<PsiElement> IN_MULTI_CATCH_TYPE = or(psiElement().afterLeaf(psiElement().withText("|").withParent(PsiTypeElement.class).withSuperParent(2, PsiCatchSection.class)), - psiElement().afterLeaf(psiElement().withText("|").withParent(PsiTypeElement.class).withSuperParent(2, PsiParameter.class).withSuperParent(3, PsiCatchSection.class))); + psiElement().afterLeaf(psiElement().withText("|").withParent(PsiTypeElement.class).withSuperParent(2, PsiParameter.class) + .withSuperParent(3, PsiCatchSection.class))); static final ElementPattern<PsiElement> INSIDE_METHOD_THROWS_CLAUSE = psiElement().afterLeaf(PsiKeyword.THROWS, ",").inside(psiElement(JavaElementType.THROWS_LIST)); static final ElementPattern<PsiElement> IN_RESOURCE_TYPE = @@ -55,15 +56,13 @@ public class PreferByKindWeigher extends LookupElementWeigher { withParent(or(psiElement(PsiResourceVariable.class), psiElement(PsiResourceList.class))))); private final CompletionType myCompletionType; private final PsiElement myPosition; - private final boolean myLocal; private final Set<PsiField> myNonInitializedFields; @NotNull private final Condition<PsiClass> myRequiredSuper; - public PreferByKindWeigher(CompletionType completionType, final PsiElement position, boolean local) { - super("kind" + (local ? "Local" : "Global")); + public PreferByKindWeigher(CompletionType completionType, final PsiElement position) { + super("kind"); myCompletionType = completionType; myPosition = position; - myLocal = local; myNonInitializedFields = JavaCompletionProcessor.getNonInitializedFields(position); myRequiredSuper = createSuitabilityCondition(position); } @@ -155,10 +154,6 @@ public class PreferByKindWeigher extends LookupElementWeigher { } } - if (myLocal) { - return MyResult.normal; - } - if (object instanceof String && item.getUserData(JavaCompletionUtil.SUPER_METHOD_PARAMETERS) == Boolean.TRUE) { return MyResult.superMethodParameters; } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java index 847dbd29b233..79a8b0423c64 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java @@ -48,12 +48,15 @@ class RecursionWeigher extends LookupElementWeigher { private final PsiExpression myCallQualifier; private final PsiExpression myPositionQualifier; private final boolean myDelegate; + private final CompletionType myCompletionType; public RecursionWeigher(PsiElement position, + CompletionType completionType, @NotNull PsiReferenceExpression reference, @Nullable PsiMethodCallExpression expression, ExpectedTypeInfo[] expectedInfos) { super("recursion"); + myCompletionType = completionType; myFilter = recursionFilter(position); myPosition = position; myReference = reference; @@ -121,7 +124,7 @@ class RecursionWeigher extends LookupElementWeigher { return Result.recursive; } - if (isPassingObjectToItself(object)) { + if (isPassingObjectToItself(object) && myCompletionType == CompletionType.SMART) { return Result.passingObjectToItself; } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/IconLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/IconLineMarkerProvider.java index d8cce7a9e081..26d89542658d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/IconLineMarkerProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/IconLineMarkerProvider.java @@ -30,12 +30,18 @@ import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.ImageLoader; +import com.intellij.util.PlatformUtils; +import com.intellij.util.io.URLUtil; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.event.MouseEvent; +import java.io.IOException; +import java.net.URL; import java.util.*; /** @@ -147,7 +153,7 @@ public class IconLineMarkerProvider implements LineMarkerProvider { || !isIconFileExtension(file.getExtension()) || file.getLength() > ICON_MAX_SIZE) continue; - final Icon icon = getIcon(file); + final Icon icon = getIcon(file, project); if (icon != null) { final Ref<VirtualFile> f = Ref.create(file); @@ -179,13 +185,13 @@ public class IconLineMarkerProvider implements LineMarkerProvider { } @Nullable - private Icon getIcon(VirtualFile file) { + private Icon getIcon(VirtualFile file, Project project) { final String path = file.getPath(); final long stamp = file.getModificationStamp(); Pair<Long, Icon> iconInfo = iconsCache.get(path); if (iconInfo == null || iconInfo.getFirst() < stamp) { try { - final Icon icon = new ImageIcon(file.contentsToByteArray()); + final Icon icon = createOrFindBetterIcon(file, PlatformUtils.isIdeaProject(project)); iconInfo = new Pair<Long, Icon>(stamp, hasProperSize(icon) ? icon : null); iconsCache.put(file.getPath(), iconInfo); } @@ -197,6 +203,42 @@ public class IconLineMarkerProvider implements LineMarkerProvider { return iconInfo == null ? null : iconInfo.getSecond(); } + private Icon createOrFindBetterIcon(VirtualFile file, boolean tryToFindBetter) throws IOException { + if (tryToFindBetter) { + VirtualFile parent = file.getParent(); + String name = file.getNameWithoutExtension(); + String ext = file.getExtension(); + VirtualFile newFile; + boolean retina = UIUtil.isRetina(); + boolean dark = UIUtil.isUnderDarcula(); + if (retina && dark) { + newFile = parent.findChild(name + "@2x_dark." + ext); + if (newFile != null) { + return loadIcon(newFile, 2); + } + } + + if (dark) { + newFile = parent.findChild(name + "_dark." + ext); + if (newFile != null) { + return loadIcon(file, 1); + } + } + + if (retina) { + newFile = parent.findChild(name + "@2x." + ext); + if (newFile != null) { + return loadIcon(newFile, 2); + } + } + } + return new ImageIcon(file.contentsToByteArray()); + } + + private ImageIcon loadIcon(VirtualFile file, int scale) throws IOException { + return new ImageIcon(ImageLoader.loadFromStream(URLUtil.openStream(new URL(file.getUrl())), scale)); + } + private static boolean isIconClassType(PsiType type) { return InheritanceUtil.isInheritor(type, JAVAX_SWING_ICON); } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaHighlightInfoTypes.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaHighlightInfoTypes.java index 39a8f5e53578..5aa830993cb2 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaHighlightInfoTypes.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaHighlightInfoTypes.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.daemon.impl; import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection; +import com.intellij.ide.highlighter.JavaHighlightingColors; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.editor.SyntaxHighlighterColors; import com.intellij.openapi.editor.colors.CodeInsightColors; @@ -30,5 +31,5 @@ public interface JavaHighlightInfoTypes extends HighlightInfoType { HighlightDisplayKey.findOrRegister(UnusedImportLocalInspection.SHORT_NAME, UnusedImportLocalInspection.DISPLAY_NAME), CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES); - HighlightInfoType JAVA_KEYWORD = new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, SyntaxHighlighterColors.KEYWORD); + HighlightInfoType JAVA_KEYWORD = new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, JavaHighlightingColors.KEYWORD); }
\ No newline at end of file diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaReferenceImporter.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaReferenceImporter.java index 95a5e619ebad..8568e03f78be 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaReferenceImporter.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaReferenceImporter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,10 @@ package com.intellij.codeInsight.daemon.impl; import com.intellij.codeInsight.daemon.ReferenceImporter; import com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFix; -import com.intellij.lang.StdLanguages; +import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiJavaCodeReferenceElement; -import com.intellij.psi.PsiReference; +import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -38,7 +35,10 @@ public class JavaReferenceImporter implements ReferenceImporter { } public static boolean autoImportReferenceAtCursor(@NotNull Editor editor, @NotNull PsiFile file, final boolean allowCaretNearRef) { - if (!file.getViewProvider().getLanguages().contains(StdLanguages.JAVA)) return false; + if (!file.getViewProvider().getLanguages().contains(JavaLanguage.INSTANCE)) { + return false; + } + int caretOffset = editor.getCaretModel().getOffset(); Document document = editor.getDocument(); int lineNumber = document.getLineNumber(caretOffset); @@ -55,14 +55,17 @@ public class JavaReferenceImporter implements ReferenceImporter { } } } + return false; } @Override public boolean autoImportReferenceAt(@NotNull Editor editor, @NotNull PsiFile file, int offset) { - if (!file.getViewProvider().getLanguages().contains(StdLanguages.JAVA)) return false; - PsiReference element = file.findReferenceAt(offset); + if (!file.getViewProvider().getLanguages().contains(JavaLanguage.INSTANCE)) { + return false; + } + PsiReference element = file.findReferenceAt(offset); if (element instanceof PsiJavaCodeReferenceElement) { PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)element; if (ref.multiResolve(true).length == 0) { @@ -70,6 +73,7 @@ public class JavaReferenceImporter implements ReferenceImporter { return true; } } + return false; } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java index ebdccd98d088..63416fa26746 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java @@ -406,6 +406,14 @@ public class AnnotationsHighlightUtil { return null; } + public static HighlightInfo checkFunctionalInterface(PsiAnnotation annotation) { + final String errorMessage = LambdaUtil.checkFunctionalInterface(annotation); + if (errorMessage != null) { + return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, annotation, errorMessage); + } + return null; + } + public static class AnnotationReturnTypeVisitor extends PsiTypeVisitor<Boolean> { public static final AnnotationReturnTypeVisitor INSTANCE = new AnnotationReturnTypeVisitor(); @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index e6124f8cfcd6..8c42592a468f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -477,6 +477,49 @@ public class GenericsHighlightUtil { if (info != null) return info; } + final PsiIdentifier classIdentifier = aClass.getNameIdentifier(); + if (PsiUtil.isLanguageLevel8OrHigher(aClass) && classIdentifier != null) { + final HighlightInfo info = checkUnrelatedDefaultMethods(aClass, signaturesWithSupers, classIdentifier); + if (info != null) return info; + } + + return null; + } + + private static HighlightInfo checkUnrelatedDefaultMethods(PsiClass aClass, + Collection<HierarchicalMethodSignature> signaturesWithSupers, + PsiIdentifier classIdentifier) { + for (HierarchicalMethodSignature methodSignature : signaturesWithSupers) { + final PsiMethod method = methodSignature.getMethod(); + if (method.hasModifierProperty(PsiModifier.DEFAULT)) { + final PsiClass containingClass = method.getContainingClass(); + List<HierarchicalMethodSignature> superSignatures = methodSignature.getSuperSignatures(); + if (!superSignatures.isEmpty()) { + for (HierarchicalMethodSignature signature : superSignatures) { + final PsiMethod superMethod = signature.getMethod(); + final PsiClass superContainingClass = superMethod.getContainingClass(); + if (containingClass != null && superContainingClass != null && !InheritanceUtil + .isInheritorOrSelf(containingClass, superContainingClass, true)) { + if (superMethod.hasModifierProperty(PsiModifier.DEFAULT)) { + final String inheritUnrelatedDefaultsMessage = HighlightUtil.formatClass(aClass) + " inherits unrelated defaults for " + + HighlightUtil.formatMethod(method) + " from types " + HighlightUtil.formatClass(containingClass) + + " and " + HighlightUtil.formatClass(superContainingClass); + return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, + classIdentifier, inheritUnrelatedDefaultsMessage); + } + if (!aClass.hasModifierProperty(PsiModifier.ABSTRACT)) { + final String message = JavaErrorMessages.message( + aClass instanceof PsiEnumConstantInitializer ? "enum.constant.should.implement.method" : "class.must.be.abstract", + HighlightUtil.formatClass(superContainingClass), + HighlightUtil.formatMethod(superMethod), + HighlightUtil.formatClass(superContainingClass, false)); + return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, classIdentifier, message); + } + } + } + } + } + } return null; } @@ -731,7 +774,7 @@ public class GenericsHighlightUtil { return true; } } - if (!TypeConversionUtil.typesAgree(lTypeArg, rTypeArg, false)) return true; + if (!TypeConversionUtil.typesAgree(lTypeArg, rTypeArg, true)) return true; } return false; } @@ -802,6 +845,11 @@ public class GenericsHighlightUtil { public static PsiType getCollectionItemType(@NotNull PsiExpression expression) { final PsiType type = expression.getType(); if (type == null) return null; + return getCollectionItemType(type, expression.getResolveScope()); + } + + @Nullable + public static PsiType getCollectionItemType(final PsiType type, final GlobalSearchScope scope) { if (type instanceof PsiArrayType) { return ((PsiArrayType)type).getComponentType(); } @@ -814,7 +862,7 @@ public class GenericsHighlightUtil { PsiSubstitutor substitutor = resolveResult.getSubstitutor(); JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); if (qName != null) { - PsiClass myClass = facade.findClass(qName, expression.getResolveScope()); + PsiClass myClass = facade.findClass(qName, scope); if (myClass != null && myClass != aClass) { //different JDKs PsiTypeParameter thisTypeParameter = getIterableTypeParameter(facade, myClass); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java index de33ce5390c9..e0eaca96611e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -230,8 +230,9 @@ public class HighlightClassUtil { @Nullable static HighlightInfo checkPublicClassInRightFile(PsiKeyword keyword, PsiModifierList psiModifierList) { - // todo most testcase classes located in wrong files + // most test case classes are located in wrong files if (ApplicationManager.getApplication().isUnitTestMode()) return null; + if (new PsiMatcherImpl(keyword) .dot(PsiMatchers.hasText(PsiModifier.PUBLIC)) .parent(PsiMatchers.hasClass(PsiModifierList.class)) @@ -240,14 +241,15 @@ public class HighlightClassUtil { .getElement() == null) { return null; } + PsiClass aClass = (PsiClass)keyword.getParent().getParent(); PsiJavaFile file = (PsiJavaFile)aClass.getContainingFile(); VirtualFile virtualFile = file.getVirtualFile(); HighlightInfo errorResult = null; - if (virtualFile != null && !aClass.getName().equals(virtualFile.getNameWithoutExtension()) && aClass.getNameIdentifier() != null) { + if (virtualFile != null && !aClass.getName().equals(virtualFile.getNameWithoutExtension())) { String message = JavaErrorMessages.message("public.class.should.be.named.after.file", aClass.getName()); - - errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, aClass.getNameIdentifier(), message); + TextRange range = HighlightNamesUtil.getClassDeclarationTextRange(aClass); + errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, range, message); IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(psiModifierList, PsiModifier.PUBLIC, false, false); QuickFixAction.registerQuickFixAction(errorResult, fix); PsiClass[] classes = file.getClasses(); @@ -255,8 +257,9 @@ public class HighlightClassUtil { QuickFixAction.registerQuickFixAction(errorResult, new MoveClassToSeparateFileFix(aClass)); } for (PsiClass otherClass : classes) { - if (!otherClass.getManager().areElementsEquivalent(otherClass, aClass) && otherClass.hasModifierProperty(PsiModifier.PUBLIC) - && otherClass.getName().equals(virtualFile.getNameWithoutExtension())) { + if (!otherClass.getManager().areElementsEquivalent(otherClass, aClass) && + otherClass.hasModifierProperty(PsiModifier.PUBLIC) && + otherClass.getName().equals(virtualFile.getNameWithoutExtension())) { return errorResult; } } @@ -267,22 +270,53 @@ public class HighlightClassUtil { } @Nullable + static HighlightInfo checkClassAndPackageConflict(@NotNull PsiClass aClass) { + String name = aClass.getQualifiedName(); + + if (CommonClassNames.DEFAULT_PACKAGE.equals(name)) { + String message = JavaErrorMessages.message("class.clashes.with.package", name); + TextRange range = HighlightNamesUtil.getClassDeclarationTextRange(aClass); + return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, range, message); + } + + PsiElement file = aClass.getParent(); + if (file instanceof PsiJavaFile && !((PsiJavaFile)file).getPackageName().isEmpty()) { + PsiElement directory = file.getParent(); + if (directory instanceof PsiDirectory) { + String simpleName = aClass.getName(); + PsiDirectory subDirectory = ((PsiDirectory)directory).findSubdirectory(simpleName); + if (subDirectory != null && simpleName.equals(subDirectory.getName())) { + String message = JavaErrorMessages.message("class.clashes.with.package", name); + TextRange range = HighlightNamesUtil.getClassDeclarationTextRange(aClass); + return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, range, message); + } + } + } + + return null; + } + + @Nullable private static HighlightInfo checkStaticFieldDeclarationInInnerClass(PsiKeyword keyword) { if (getEnclosingStaticClass(keyword, PsiField.class) == null) { return null; } + PsiField field = (PsiField)keyword.getParent().getParent(); - if (PsiUtilCore.hasErrorElementChild(field)) return null; - // except compile time constants - if (PsiUtil.isCompileTimeConstant(field)) { + if (PsiUtilCore.hasErrorElementChild(field) || PsiUtil.isCompileTimeConstant(field)) { return null; } + String message = JavaErrorMessages.message("static.declaration.in.inner.class"); HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, keyword, message); - IntentionAction fix1 = QUICK_FIX_FACTORY.createModifierListFix(field, PsiModifier.STATIC, false, false); - QuickFixAction.registerQuickFixAction(errorResult, fix1); - IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(field.getContainingClass(), PsiModifier.STATIC, true, false); - QuickFixAction.registerQuickFixAction(errorResult, fix); + + QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createModifierListFix(field, PsiModifier.STATIC, false, false)); + + PsiClass aClass = field.getContainingClass(); + if (aClass != null) { + QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createModifierListFix(aClass, PsiModifier.STATIC, true, false)); + } + return errorResult; } @@ -661,7 +695,7 @@ public class HighlightClassUtil { IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(aClass, PsiModifier.STATIC, false, false); QuickFixAction.registerQuickFixAction(info, fix); } - + } else if (aClass instanceof PsiAnonymousClass) { final PsiClass baseClass = PsiUtil.resolveClassInType(((PsiAnonymousClass)aClass).getBaseClassType()); if (baseClass != null && baseClass.isInterface()) { @@ -952,7 +986,7 @@ public class HighlightClassUtil { PsiNewExpression newExpression = (PsiNewExpression)JavaPsiFacade.getElementFactory(project).createExpressionFromText(startElement.getText() + "{}", startElement); newExpression = (PsiNewExpression)startElement.replace(newExpression); - final PsiClass psiClass = newExpression.getAnonymousClass(); + final PsiClass psiClass = newExpression.getAnonymousClass(); if (psiClass == null) return; PsiClassType baseClassType = ((PsiAnonymousClass)psiClass).getBaseClassType(); PsiClass resolve = baseClassType.resolve(); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index e4c7098f6a21..d7f106a4852b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -712,7 +712,7 @@ public class HighlightMethodUtil { PsiType type = expression.getType(); boolean showShort = showShortType(i, parameters, expressions, substitutor); - @NonNls String mismatchColor = showShort ? null : "red"; + @NonNls String mismatchColor = showShort ? null : (UIUtil.isUnderDarcula() ? "ff6464" : "red"); ms += "<td> " + "<b><nobr>" + (i == 0 ? "(" : "") + "<font " + (showShort ? "" : "color=" + mismatchColor) + ">" + XmlStringUtil.escapeString(showShort ? type.getPresentableText() : HighlightUtil.formatType(type)) @@ -853,21 +853,24 @@ public class HighlightMethodUtil { @Nullable static HighlightInfo checkMethodCanHaveBody(PsiMethod method) { PsiClass aClass = method.getContainingClass(); - boolean hasBody = method.getBody() == null; + boolean hasNoBody = method.getBody() == null; boolean isInterface = aClass != null && aClass.isInterface(); boolean isExtension = method.hasModifierProperty(PsiModifier.DEFAULT); + boolean isStatic = method.hasModifierProperty(PsiModifier.STATIC); String message = null; - if (hasBody) { + if (hasNoBody) { if (isExtension) { message = JavaErrorMessages.message("extension.method.should.have.a.body"); + } else if (isInterface && isStatic) { + message = "Static methods in interfaces should have a body"; } } else if (isInterface) { - if (!isExtension) { + if (!isExtension && !isStatic) { message = JavaErrorMessages.message("interface.methods.cannot.have.body"); } - else { + else if (isExtension) { return HighlightUtil.checkExtensionMethodsFeature(method); } } @@ -884,7 +887,7 @@ public class HighlightMethodUtil { TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method); HighlightInfo info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, textRange, message); - if (hasBody) { + if (hasNoBody) { QuickFixAction.registerQuickFixAction(info, new DeleteMethodBodyFix(method)); } if (method.hasModifierProperty(PsiModifier.ABSTRACT) && isInterface) { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index d880cae77f33..dbacc36fc421 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -30,12 +30,15 @@ import com.intellij.lang.findUsages.LanguageFindUsages; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.impl.source.jsp.jspJava.JspClass; @@ -45,6 +48,7 @@ import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.jsp.JspFile; import com.intellij.psi.scope.processor.VariablesNotProcessor; import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.templateLanguages.OuterLanguageElement; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.*; @@ -63,6 +67,8 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.PropertyKey; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static com.intellij.util.containers.ContainerUtil.newTroveSet; @@ -155,7 +161,13 @@ public class HighlightUtil extends HighlightUtilBase { Set<String> incompatibles = incompatibleModifiersHash.get(modifier); if (incompatibles == null) return null; + final boolean level8OrHigher = PsiUtil.isLanguageLevel8OrHigher(modifierList); for (@PsiModifier.ModifierConstant String incompatible : incompatibles) { + if (level8OrHigher) { + if (modifier.equals(PsiModifier.STATIC) && incompatible.equals(PsiModifier.ABSTRACT)){ + continue; + } + } if (modifierList.hasModifierProperty(incompatible)) { return incompatible; } @@ -833,27 +845,35 @@ public class HighlightUtil extends HighlightUtilBase { @Nullable public static HighlightInfo checkLiteralExpressionParsingError(@NotNull final PsiLiteralExpression expression) { - final Object value = expression.getValue(); - final PsiElement literal = expression.getFirstChild(); + PsiElement literal = expression.getFirstChild(); assert literal instanceof PsiJavaToken : literal; - final IElementType type = ((PsiJavaToken)literal).getTokenType(); - String text = PsiLiteralExpressionImpl.NUMERIC_LITERALS.contains(type) ? literal.getText().toLowerCase() : literal.getText(); + IElementType type = ((PsiJavaToken)literal).getTokenType(); + if (type == JavaTokenType.TRUE_KEYWORD || type == JavaTokenType.FALSE_KEYWORD || type == JavaTokenType.NULL_KEYWORD) { + return null; + } + + boolean isInt = PsiLiteralExpressionImpl.INTEGER_LITERALS.contains(type); + boolean isFP = PsiLiteralExpressionImpl.REAL_LITERALS.contains(type); + String text = isInt || isFP ? literal.getText().toLowerCase() : literal.getText(); + Object value = expression.getValue(); - if (PsiLiteralExpressionImpl.REAL_LITERALS.contains(type)) { + if (isFP) { if (text.startsWith(PsiLiteralExpressionImpl.HEX_PREFIX)) { final HighlightInfo info = checkFeature(expression, Feature.HEX_FP_LITERALS); if (info != null) return info; } } - if (PsiLiteralExpressionImpl.INTEGER_LITERALS.contains(type)) { + if (isInt) { if (text.startsWith(PsiLiteralExpressionImpl.BIN_PREFIX)) { final HighlightInfo info = checkFeature(expression, Feature.BIN_LITERALS); if (info != null) return info; } } - if (PsiLiteralExpressionImpl.NUMERIC_LITERALS.contains(type)) { + if (isInt || isFP) { if (text.contains("_")) { - final HighlightInfo info = checkFeature(expression, Feature.UNDERSCORES); + HighlightInfo info = checkFeature(expression, Feature.UNDERSCORES); + if (info != null) return info; + info = checkUnderscores(expression, text, isInt); if (info != null) return info; } } @@ -898,15 +918,12 @@ public class HighlightUtil extends HighlightUtilBase { } } } - else if (type == JavaTokenType.FLOAT_LITERAL || type == JavaTokenType.DOUBLE_LITERAL) { + else if (isFP) { if (value == null) { final String message = JavaErrorMessages.message("malformed.floating.point.literal"); return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, message); } } - else if (type == JavaTokenType.TRUE_KEYWORD || type == JavaTokenType.FALSE_KEYWORD || type == JavaTokenType.NULL_KEYWORD) { - return null; - } else if (type == JavaTokenType.CHARACTER_LITERAL) { // todo[r.sh] clean this mess up if (value != null) { @@ -1003,6 +1020,43 @@ public class HighlightUtil extends HighlightUtilBase { return null; } + private static final Pattern FP_LITERAL_PARTS = + Pattern.compile("(?:" + + "(?:0x([_\\p{XDigit}]*)\\.?([_\\p{XDigit}]*)p[+-]?([_\\d]*))" + + "|" + + "(?:([_\\d]*)\\.?([_\\d]*)e?[+-]?([_\\d]*))" + + ")[fd]?"); + + @Nullable + private static HighlightInfo checkUnderscores(PsiElement expression, String text, boolean isInt) { + String[] parts = ArrayUtil.EMPTY_STRING_ARRAY; + + if (isInt) { + int start = 0, end = text.length(); + if (text.startsWith(PsiLiteralExpressionImpl.HEX_PREFIX) || text.startsWith(PsiLiteralExpressionImpl.BIN_PREFIX)) start += 2; + if (StringUtil.endsWithChar(text, 'l')) --end; + parts = new String[]{text.substring(start, end)}; + } + else { + Matcher matcher = FP_LITERAL_PARTS.matcher(text); + if (matcher.matches()) { + parts = new String[matcher.groupCount()]; + for (int i = 0; i < matcher.groupCount(); i++) { + parts[i] = matcher.group(i + 1); + } + } + } + + for (String part : parts) { + if (part != null && (StringUtil.startsWithChar(part, '_') || StringUtil.endsWithChar(part, '_'))) { + String message = JavaErrorMessages.message("illegal.underscore"); + return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, message); + } + } + + return null; + } + // true if floating point literal consists of zeros only public static boolean isFPZero(@NotNull final String text) { for (int i = 0; i < text.length(); i++) { @@ -1890,6 +1944,14 @@ public class HighlightUtil extends HighlightUtilBase { return highlightInfo; } + + if (element instanceof PsiReferenceExpression) { + final PsiElement resolve = ((PsiReferenceExpression)element).resolve(); + if (resolve instanceof PsiField && ((PsiField)resolve).hasModifierProperty(PsiModifier.STATIC)) { + return null; + } + } + element = element.getParent(); if (element instanceof PsiClass && InheritanceUtil.isInheritorOrSelf((PsiClass)element, referencedClass, true)) return null; } @@ -2418,6 +2480,26 @@ public class HighlightUtil extends HighlightUtilBase { } @Nullable + static HighlightInfo checkPackageAndClassConflict(@NotNull PsiJavaCodeReferenceElement ref) { + if (ref.isQualified() && isInsidePackageStatement(ref)) { + VirtualFile file = ref.getContainingFile().getVirtualFile(); + if (file != null) { + Module module = ProjectFileIndex.SERVICE.getInstance(ref.getProject()).getModuleForFile(file); + if (module != null) { + GlobalSearchScope scope = module.getModuleWithDependenciesAndLibrariesScope(false); + PsiClass aClass = JavaPsiFacade.getInstance(ref.getProject()).findClass(ref.getCanonicalText(), scope); + if (aClass != null) { + String message = JavaErrorMessages.message("package.clashes.with.class", ref.getText()); + return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, ref, message); + } + } + } + } + + return null; + } + + @Nullable static HighlightInfo checkElementInReferenceList(@NotNull PsiJavaCodeReferenceElement ref, @NotNull PsiReferenceList referenceList, @NotNull JavaResolveResult resolveResult) { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index ad0369bf908c..2db8816d2df1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -182,6 +182,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkTargetAnnotationDuplicates(annotation)); if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkDuplicateAnnotations(annotation)); if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkForeignInnerClassesUsed(annotation)); + if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkFunctionalInterface(annotation)); } @Override @@ -269,7 +270,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); for (int i = 0; i < lambdaParameters.length; i++) { PsiParameter lambdaParameter = lambdaParameters[i]; - if (!TypeConversionUtil.isAssignable(LambdaUtil.getSubstitutor(interfaceMethod, resolveResult).substitute(parameters[i].getType()), lambdaParameter.getType())) { + if (!TypeConversionUtil.isAssignable(lambdaParameter.getType(), + GenericsUtil.eliminateWildcards(LambdaUtil.getSubstitutor(interfaceMethod, resolveResult).substitute(parameters[i].getType())))) { myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, lambdaParameter, incompatibleTypesMessage)); break; } @@ -300,13 +302,15 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } } - @Override public void visitClass(PsiClass aClass) { + @Override + public void visitClass(PsiClass aClass) { super.visitClass(aClass); if (aClass instanceof JspClass) return; if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkInterfaceMultipleInheritance(aClass)); if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkDuplicateTopLevelClass(aClass)); if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumMustNotBeLocal(aClass)); if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkImplicitThisReferenceBeforeSuper(aClass)); + if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkClassAndPackageConflict(aClass)); } @Override public void visitClassInitializer(PsiClassInitializer initializer) { @@ -783,7 +787,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh if (!myHolder.hasErrorResults()) visitExpression(expression); } - @Override public void visitPackageStatement(PsiPackageStatement statement) { + @Override + public void visitPackageStatement(PsiPackageStatement statement) { super.visitPackageStatement(statement); myHolder.add(AnnotationsHighlightUtil.checkPackageAnnotationContainingFile(statement)); } @@ -878,7 +883,9 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh PsiVariable variable = (PsiVariable)resolved; final PsiClass containingClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class); - if (containingClass instanceof PsiAnonymousClass && !PsiTreeUtil.isAncestor(containingClass, variable, false) && !(variable instanceof PsiField)) { + if (containingClass instanceof PsiAnonymousClass && + !PsiTreeUtil.isAncestor(containingClass, variable, false) && + !(variable instanceof PsiField)) { if (!PsiTreeUtil.isAncestor(((PsiAnonymousClass) containingClass).getArgumentList(), ref, false)) { myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.IMPLICIT_ANONYMOUS_CLASS_PARAMETER, ref, null)); } @@ -927,7 +934,9 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } } } - + + if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkPackageAndClassConflict(ref)); + return result; } @@ -1022,6 +1031,9 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } } } + if (!myHolder.hasErrorResults()) { + myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, expression.getTextRange())); + } } @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java index c6b5b8c25f44..43bd4c035828 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -190,10 +190,12 @@ public class CreateClassFromNewFix extends CreateFromUsageBaseFix { if (aClass.isInterface()) { PsiReferenceList implementsList = targetClass.getImplementsList(); + assert implementsList != null : targetClass; implementsList.add(factory.createReferenceElementByType(classType)); } else { PsiReferenceList extendsList = targetClass.getExtendsList(); + assert extendsList != null : targetClass; if (extendsList.getReferencedTypes().length == 0 && !CommonClassNames.JAVA_LANG_OBJECT.equals(classType.getCanonicalText())) { extendsList.add(factory.createReferenceElementByType(classType)); } @@ -201,7 +203,6 @@ public class CreateClassFromNewFix extends CreateFromUsageBaseFix { } } - private static PsiFile getTargetFile(PsiElement element) { PsiJavaCodeReferenceElement referenceElement = getReferenceElement((PsiNewExpression)element); @@ -242,14 +243,18 @@ public class CreateClassFromNewFix extends CreateFromUsageBaseFix { @Override protected boolean isAvailableImpl(int offset) { - PsiElement nameElement = getNameElement(getNewExpression()); + PsiNewExpression expression = getNewExpression(); + if (expression.getQualifier() != null) { + return false; + } - PsiFile targetFile = getTargetFile(getNewExpression()); + PsiFile targetFile = getTargetFile(expression); if (targetFile != null && !targetFile.getManager().isInProject(targetFile)) { return false; } - if (CreateFromUsageUtils.shouldShowTag(offset, nameElement, getNewExpression())) { + PsiElement nameElement = getNameElement(expression); + if (CreateFromUsageUtils.shouldShowTag(offset, nameElement, expression)) { String varName = nameElement.getText(); setText(getText(varName)); return true; @@ -268,8 +273,7 @@ public class CreateClassFromNewFix extends CreateFromUsageBaseFix { private static PsiElement getNameElement(PsiNewExpression targetElement) { PsiJavaCodeReferenceElement referenceElement = getReferenceElement(targetElement); - if (referenceElement == null) return null; - return referenceElement.getReferenceNameElement(); + return referenceElement != null ? referenceElement.getReferenceNameElement() : null; } @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallFix.java index a3678f505e4b..7fcbd9860bda 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallFix.java @@ -31,6 +31,8 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import java.util.List; + /** * @author mike */ @@ -140,7 +142,9 @@ public class CreateConstructorFromCallFix extends CreateFromUsageBaseFix { PsiConstructorCall constructorCall = (PsiConstructorCall)element; PsiMethod method = constructorCall.resolveConstructor(); PsiExpressionList argumentList = constructorCall.getArgumentList(); - PsiClass targetClass = getTargetClasses(constructorCall).get(0); + List<PsiClass> targetClasses = getTargetClasses(constructorCall); + if (targetClasses.isEmpty()) return false; + PsiClass targetClass = targetClasses.get(0); return !CreateFromUsageUtils.shouldCreateConstructor(targetClass, argumentList, method); } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperFix.java index 8b13030f20f3..09fcdeb447e4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -26,7 +26,6 @@ import com.intellij.openapi.command.undo.UndoUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; -import com.intellij.openapi.editor.ex.RangeMarkerEx; import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; @@ -65,7 +64,7 @@ public abstract class CreateConstructorFromThisOrSuperFix extends CreateFromUsag if (method == null || !method.isConstructor()) return false; if (CreateMethodFromUsageFix.hasErrorsInArgumentList(myMethodCall)) return false; List<PsiClass> targetClasses = getTargetClasses(myMethodCall); - LOG.assertTrue(targetClasses.size() == 1); + if (targetClasses.isEmpty()) return false; if (CreateFromUsageUtils.shouldShowTag(offset, ref.getReferenceNameElement(), myMethodCall)) { setText(QuickFixBundle.message("create.constructor.text", targetClasses.get(0).getName())); @@ -144,9 +143,8 @@ public abstract class CreateConstructorFromThisOrSuperFix extends CreateFromUsag PsiMethodCallExpression methodCall = (PsiMethodCallExpression) element; PsiMethod method = (PsiMethod) methodCall.getMethodExpression().resolve(); PsiExpressionList argumentList = methodCall.getArgumentList(); - PsiClass targetClass = getTargetClasses(element).get(0); - - return !CreateFromUsageUtils.shouldCreateConstructor(targetClass, argumentList, method); + List<PsiClass> classes = getTargetClasses(element); + return classes.size() > 0 && !CreateFromUsageUtils.shouldCreateConstructor(classes.get(0), argumentList, method); } @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java index 845bcdecc33d..83b43424bad2 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -54,19 +54,20 @@ import java.util.*; public abstract class CreateFromUsageBaseFix extends BaseIntentionAction { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageBaseFix"); - protected CreateFromUsageBaseFix() { - } - @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - int offset = editor.getCaretModel().getOffset(); PsiElement element = getElement(); - if (element == null) { + if (element == null || isValidElement(element)) { + return false; + } + + int offset = editor.getCaretModel().getOffset(); + if (!isAvailableImpl(offset)) { return false; } List<PsiClass> targetClasses = getTargetClasses(element); - return !targetClasses.isEmpty() && !isValidElement(element) && isAvailableImpl(offset); + return !targetClasses.isEmpty(); } protected abstract boolean isAvailableImpl(int offset); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java index e2b2e10f7701..962c90a91846 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java @@ -664,7 +664,7 @@ public class CreateFromUsageUtils { expectedTypes = union.toArray(new ExpectedTypeInfo[union.size()]); } - if (expectedTypes == null || expectedTypes.length == 0) { + if (expectedTypes.length == 0) { PsiType t = allowVoidType ? PsiType.VOID : PsiType.getJavaLangObject(manager, resolveScope); expectedTypes = new ExpectedTypeInfo[] {ExpectedTypesProvider.createInfo(t, ExpectedTypeInfo.TYPE_OR_SUBTYPE, t, TailType.NONE)}; } @@ -716,7 +716,7 @@ public class CreateFromUsageUtils { expectedTypes = union.toArray(new ExpectedTypeInfo[union.size()]); } - if (expectedTypes == null || expectedTypes.length == 0) { + if (expectedTypes.length == 0) { return allowVoidType ? new PsiType[]{PsiType.VOID} : new PsiType[]{PsiType.getJavaLangObject(manager, resolveScope)}; } else { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java index 5b16e4929b7a..22d4cbdb1a61 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java @@ -154,8 +154,8 @@ public class CreateLocalFromUsageFix extends CreateVarFromUsageFix { minOffset = Math.min(minOffset, expressionOccurences[i].getTextRange().getStartOffset()); } - PsiCodeBlock block = (PsiCodeBlock) (parent instanceof PsiCodeBlock ? parent : PsiTreeUtil.getParentOfType(parent, PsiCodeBlock.class)); - LOG.assertTrue(block != null && block.getStatements().length > 0); + final PsiCodeBlock block = PsiTreeUtil.getParentOfType(parent, PsiCodeBlock.class, false); + LOG.assertTrue(block != null && block.getStatements().length > 0, block); PsiStatement[] statements = block.getStatements(); for (int i = 1; i < statements.length; i++) { if (statements[i].getTextRange().getStartOffset() > minOffset) return statements[i-1]; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalVarFromInstanceofAction.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalVarFromInstanceofAction.java index e7d6af11325f..7ffba61c3246 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalVarFromInstanceofAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalVarFromInstanceofAction.java @@ -35,6 +35,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.codeStyle.SuggestedNameInfo; import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodQuickFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodQuickFix.java index 28de8496e7aa..a1323ae5fd90 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodQuickFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodQuickFix.java @@ -18,8 +18,8 @@ package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.CodeInsightUtilBase; import com.intellij.codeInsight.ExpectedTypeInfo; import com.intellij.codeInsight.daemon.QuickFixBundle; -import com.intellij.codeInspection.LocalQuickFix; -import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.IntentionAndQuickFixAction; +import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; @@ -35,7 +35,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; -public class CreateMethodQuickFix implements LocalQuickFix { +public class CreateMethodQuickFix extends IntentionAndQuickFixAction { protected final PsiClass myTargetClass; protected final String mySignature; protected final String myBody; @@ -66,10 +66,10 @@ public class CreateMethodQuickFix implements LocalQuickFix { } @Override - public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) { + public void applyFix(Project project, PsiFile file, @Nullable Editor editor) { if (!CodeInsightUtilBase.preparePsiElementForWrite(myTargetClass.getContainingFile())) return; - PsiMethod method = createMethod(project); + PsiMethod method = createMethod(project); List<Pair<PsiExpression, PsiType>> arguments = ContainerUtil.map2List(method.getParameterList().getParameters(), new Function<PsiParameter, Pair<PsiExpression, PsiType>>() { @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefaultQuickFixProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefaultQuickFixProvider.java index 71b3176e7a29..b30a19f52b66 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefaultQuickFixProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefaultQuickFixProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -36,7 +36,9 @@ public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider public void registerFixes(PsiJavaCodeReferenceElement ref, QuickFixActionRegistrar registrar) { registrar.register(new ImportClassFix(ref)); registrar.register(SetupJDKFix.getInstance()); + OrderEntryFix.registerFixes(registrar, ref); + MoveClassToModuleFix.registerFixes(registrar, ref); if (ref instanceof PsiReferenceExpression) { @@ -50,7 +52,7 @@ public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider registrar.register(fixRange, new BringVariableIntoScopeFix(refExpr), null); } - registerPriorityActions(registrar,fixRange,refExpr); + registerPriorityActions(registrar, fixRange, refExpr); } registrar.register(new CreateClassFromUsageFix(ref, CreateClassKind.INTERFACE)); @@ -58,9 +60,12 @@ public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider registrar.register(new CreateClassFromUsageFix(ref, CreateClassKind.ENUM)); registrar.register(new CreateClassFromUsageFix(ref, CreateClassKind.ANNOTATION)); } + PsiElement parent = PsiTreeUtil.getParentOfType(ref, PsiNewExpression.class, PsiMethod.class); - final PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(ref, PsiExpressionList.class); - if (parent instanceof PsiNewExpression && !(ref.getParent() instanceof PsiTypeElement) && (expressionList == null || !PsiTreeUtil.isAncestor(parent, expressionList, false))) { + PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(ref, PsiExpressionList.class); + if (parent instanceof PsiNewExpression && + !(ref.getParent() instanceof PsiTypeElement) && + (expressionList == null || !PsiTreeUtil.isAncestor(parent, expressionList, false))) { registrar.register(new CreateClassFromNewFix((PsiNewExpression)parent)); registrar.register(new CreateInnerClassFromNewFix((PsiNewExpression)parent)); } @@ -70,35 +75,31 @@ public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider } } - private static void registerPriorityActions(@NotNull final QuickFixActionRegistrar registrar, - @NotNull final TextRange fixRange, - @NotNull final PsiReferenceExpression refExpr) { + private static void registerPriorityActions(@NotNull QuickFixActionRegistrar registrar, + @NotNull TextRange fixRange, + @NotNull PsiReferenceExpression refExpr) { final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(refExpr.getProject()); - final Map<VariableKind, IntentionAction> map = new HashMap<VariableKind, IntentionAction>() { - { - put(VariableKind.FIELD, new CreateFieldFromUsageFix(refExpr)); - put(VariableKind.STATIC_FINAL_FIELD, new CreateConstantFieldFromUsageFix(refExpr)); - if (!refExpr.isQualified()) { - put(VariableKind.LOCAL_VARIABLE, new CreateLocalFromUsageFix(refExpr)); - put(VariableKind.PARAMETER, new CreateParameterFromUsageFix(refExpr)); - } - } - }; + final Map<VariableKind, IntentionAction> map = new HashMap<VariableKind, IntentionAction>(); + map.put(VariableKind.FIELD, new CreateFieldFromUsageFix(refExpr)); + map.put(VariableKind.STATIC_FINAL_FIELD, new CreateConstantFieldFromUsageFix(refExpr)); + if (!refExpr.isQualified()) { + map.put(VariableKind.LOCAL_VARIABLE, new CreateLocalFromUsageFix(refExpr)); + map.put(VariableKind.PARAMETER, new CreateParameterFromUsageFix(refExpr)); + } final VariableKind kind = getKind(styleManager, refExpr); - if (map.containsKey(kind)){ + if (map.containsKey(kind)) { map.put(kind, PriorityIntentionActionWrapper.highPriority(map.get(kind))); } - for (IntentionAction action : map.values()){ + for (IntentionAction action : map.values()) { registrar.register(fixRange, action, null); } } @NotNull - private static VariableKind getKind(@NotNull JavaCodeStyleManager styleManager, - @NotNull PsiReferenceExpression refExpr) { + private static VariableKind getKind(@NotNull JavaCodeStyleManager styleManager, @NotNull PsiReferenceExpression refExpr) { final String reference = refExpr.getText(); if (reference.toUpperCase().equals(reference)){ diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java index f9fcb60ec405..ca346d3a3742 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java @@ -32,9 +32,9 @@ import org.jetbrains.annotations.NotNull; import java.util.List; -public class ImportClassFix extends ImportClassFixBase<PsiJavaCodeReferenceElement> { +public class ImportClassFix extends ImportClassFixBase<PsiJavaCodeReferenceElement, PsiJavaCodeReferenceElement> { public ImportClassFix(@NotNull PsiJavaCodeReferenceElement element) { - super(element); + super(element, element); } @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java index 7430053cc546..067c6bdb2fe0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -57,32 +57,40 @@ import java.util.regex.PatternSyntaxException; /** * @author peter */ -public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> implements HintAction, HighPriorityAction { - private final T myRef; +public abstract class ImportClassFixBase<T extends PsiElement, R extends PsiReference> implements HintAction, HighPriorityAction { + private final T myElement; + private final R myRef; - protected ImportClassFixBase(@NotNull T ref) { + protected ImportClassFixBase(@NotNull T elem, R ref) { + myElement = elem; myRef = ref; } @Override public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiFile file) { - if (!myRef.isValid()) { + if (!myElement.isValid()) { return false; } + + PsiElement parent = myElement.getParent(); + if (parent instanceof PsiNewExpression && ((PsiNewExpression)parent).getQualifier() != null) { + return false; + } + PsiManager manager = file.getManager(); return manager.isInProject(file) && !getClassesToImport().isEmpty(); } @Nullable - protected abstract String getReferenceName(@NotNull T reference); - protected abstract PsiElement getReferenceNameElement(@NotNull T reference); - protected abstract boolean hasTypeParameters(@NotNull T reference); + protected abstract String getReferenceName(@NotNull R reference); + protected abstract PsiElement getReferenceNameElement(@NotNull R reference); + protected abstract boolean hasTypeParameters(@NotNull R reference); @NotNull public List<PsiClass> getClassesToImport() { - PsiShortNamesCache cache = PsiShortNamesCache.getInstance(myRef.getProject()); + PsiShortNamesCache cache = PsiShortNamesCache.getInstance(myElement.getProject()); String name = getReferenceName(myRef); - GlobalSearchScope scope = myRef.getResolveScope(); + GlobalSearchScope scope = myElement.getResolveScope(); if (name == null) { return Collections.emptyList(); } @@ -90,7 +98,7 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im PsiClass[] classes = cache.getClassesByName(name, scope); if (classes.length == 0) return Collections.emptyList(); List<PsiClass> classList = new ArrayList<PsiClass>(classes.length); - boolean isAnnotationReference = myRef.getParent() instanceof PsiAnnotation; + boolean isAnnotationReference = myElement.getParent() instanceof PsiAnnotation; for (PsiClass aClass : classes) { if (isAnnotationReference && !aClass.isAnnotationType()) continue; if (JavaCompletionUtil.isInExcludedPackage(aClass, false)) continue; @@ -99,26 +107,26 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im if (qName != null) { //filter local classes if (qName.indexOf('.') == -1) continue; //do not show classes from default package) if (qName.endsWith(name)) { - if (isAccessible(aClass, myRef)) { + if (isAccessible(aClass, myElement)) { classList.add(aClass); } } } } - final String memberName = getRequiredMemberName(myRef); + final String memberName = getRequiredMemberName(myElement); if (memberName != null) { List<PsiClass> filtered = ContainerUtil.findAll(classList, new Condition<PsiClass>() { @Override public boolean value(PsiClass psiClass) { PsiField field = psiClass.findFieldByName(memberName, true); - if (field != null && field.hasModifierProperty(PsiModifier.STATIC) && isAccessible(field, myRef)) return true; + if (field != null && field.hasModifierProperty(PsiModifier.STATIC) && isAccessible(field, myElement)) return true; PsiClass inner = psiClass.findInnerClassByName(memberName, true); - if (inner != null && isAccessible(inner, myRef)) return true; + if (inner != null && isAccessible(inner, myElement)) return true; for (PsiMethod method : psiClass.findMethodsByName(memberName, true)) { - if (method.hasModifierProperty(PsiModifier.STATIC) && isAccessible(method, myRef)) return true; + if (method.hasModifierProperty(PsiModifier.STATIC) && isAccessible(method, myElement)) return true; } return false; } @@ -128,7 +136,7 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im } } - List<PsiClass> filtered = filterByContext(classList, myRef); + List<PsiClass> filtered = filterByContext(classList, myElement); if (!filtered.isEmpty()) { classList = filtered; } @@ -173,7 +181,7 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im if (classesToImport.isEmpty()) return Result.POPUP_NOT_SHOWN; try { - String name = getQualifiedName(myRef); + String name = getQualifiedName(myElement); if (name != null) { Pattern pattern = Pattern.compile(DaemonCodeAnalyzerSettings.getInstance().NO_AUTO_IMPORT_PATTERN); Matcher matcher = pattern.matcher(name); @@ -185,12 +193,12 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im catch (PatternSyntaxException e) { //ignore } - final PsiFile psiFile = myRef.getContainingFile(); + final PsiFile psiFile = myElement.getContainingFile(); if (classesToImport.size() > 1) { reduceSuggestedClassesBasedOnDependencyRuleViolation(psiFile, classesToImport); } PsiClass[] classes = classesToImport.toArray(new PsiClass[classesToImport.size()]); - final Project project = myRef.getProject(); + final Project project = myElement.getProject(); CodeInsightUtil.sortIdenticalShortNameClasses(classes, myRef); final QuestionAction action = createAddImportAction(classes, project, editor); @@ -220,14 +228,22 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im if (allowPopup && canImportHere) { String hintText = ShowAutoImportPass.getMessage(classes.length > 1, classes[0].getQualifiedName()); if (!ApplicationManager.getApplication().isUnitTestMode() && !HintManager.getInstance().hasShownHintsThatWillHideByOtherHint(true)) { - HintManager.getInstance().showQuestionHint(editor, hintText, myRef.getTextOffset(), - myRef.getTextRange().getEndOffset(), action); + HintManager.getInstance().showQuestionHint(editor, hintText, getStartOffset(myElement, myRef), + getEndOffset(myElement, myRef), action); } return Result.POPUP_SHOWN; } return Result.POPUP_NOT_SHOWN; } + protected int getStartOffset(T element, R ref) { + return element.getTextOffset(); + } + + protected int getEndOffset(T element, R ref) { + return element.getTextRange().getEndOffset(); + } + private static boolean autoImportWillInsertUnexpectedCharacters(PsiClass aClass) { PsiClass containingClass = aClass.getContainingClass(); // when importing inner class, the reference might be qualified with outer class name and it can be confusing @@ -239,7 +255,7 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im !hasUnresolvedImportWhichCanImport(psiFile, exampleClassName); } - protected abstract boolean isQualified(T reference); + protected abstract boolean isQualified(R reference); @Override public boolean showHint(final Editor editor) { @@ -284,7 +300,7 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im } } - private boolean isCaretNearRef(@NotNull Editor editor, @NotNull T ref) { + private boolean isCaretNearRef(@NotNull Editor editor, @NotNull R ref) { PsiElement nameElement = getReferenceNameElement(ref); if (nameElement == null) return false; TextRange range = nameElement.getTextRange(); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java index 60282d1be91b..b9f69e3c84e7 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java @@ -186,7 +186,8 @@ public class StaticImportMethodFix implements IntentionAction { .inferTypeArguments(method.getTypeParameters(), method.getParameterList().getParameters(), argumentList.getExpressions(), PsiSubstitutor.EMPTY, element.getParent(), DefaultParameterTypeInferencePolicy.INSTANCE); if (PsiUtil.isApplicable(method, substitutorForMethod, argumentList)) { - if (expectedType == null || TypeConversionUtil.isAssignable(expectedType, substitutorForMethod.substitute(method.getReturnType()))) { + final PsiType returnType = substitutorForMethod.substitute(method.getReturnType()); + if (expectedType == null || returnType == null || TypeConversionUtil.isAssignable(expectedType, returnType)) { applicableList.add(method); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchFix.java index a64fd51e8e61..97dd2ce2f339 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SurroundWithTryCatchFix.java @@ -38,10 +38,16 @@ import org.jetbrains.annotations.NotNull; public class SurroundWithTryCatchFix implements IntentionAction { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.SurroundWithTryCatchFix"); - private PsiStatement myStatement; + private PsiStatement myStatement = null; public SurroundWithTryCatchFix(PsiElement element) { - myStatement = PsiTreeUtil.getNonStrictParentOfType(element, PsiStatement.class); + final PsiMethodReferenceExpression methodReferenceExpression = PsiTreeUtil.getParentOfType(element, PsiMethodReferenceExpression.class, false); + if (methodReferenceExpression == null) { + final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class); + if (lambdaExpression == null || lambdaExpression.getBody() instanceof PsiCodeBlock) { + myStatement = PsiTreeUtil.getNonStrictParentOfType(element, PsiStatement.class); + } + } } @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ParameterListFixer.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ParameterListFixer.java index 586f7a75deef..70812b1a3fa0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ParameterListFixer.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/ParameterListFixer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -23,23 +23,21 @@ import com.intellij.psi.PsiParameterList; import com.intellij.util.IncorrectOperationException; /** - * Created by IntelliJ IDEA. - * User: max - * Date: Sep 5, 2003 - * Time: 9:30:02 PM - * To change this template use Options | File Templates. + * @author max + * @since Sep 5, 2003 */ public class ParameterListFixer implements Fixer { @Override public void apply(Editor editor, JavaSmartEnterProcessor processor, PsiElement psiElement) throws IncorrectOperationException { if (psiElement instanceof PsiParameterList) { - if (!StringUtil.endsWithChar(psiElement.getText(), ')')) { + String text = psiElement.getText(); + if (StringUtil.startsWithChar(text, '(') && !StringUtil.endsWithChar(text, ')')) { + PsiParameter[] params = ((PsiParameterList)psiElement).getParameters(); int offset; - PsiParameterList list = (PsiParameterList) psiElement; - final PsiParameter[] params = list.getParameters(); - if (params == null || params.length == 0) { - offset = list.getTextRange().getStartOffset() + 1; - } else { + if (params.length == 0) { + offset = psiElement.getTextRange().getStartOffset() + 1; + } + else { offset = params[params.length - 1].getTextRange().getEndOffset(); } editor.getDocument().insertString(offset, ")"); diff --git a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaElementSignatureProvider.java b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaElementSignatureProvider.java index 26ef1e9e13f5..1d54cca4833b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaElementSignatureProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaElementSignatureProvider.java @@ -32,9 +32,12 @@ public class JavaElementSignatureProvider extends AbstractElementSignatureProvid @Override @Nullable public String getSignature(@NotNull final PsiElement element) { + PsiFile file = element.getContainingFile(); + if (!(file instanceof PsiJavaFile)) { + return null; + } if (element instanceof PsiImportList) { - PsiFile file = element.getContainingFile(); - if (file instanceof PsiJavaFile && element.equals(((PsiJavaFile)file).getImportList())) { + if (element.equals(((PsiJavaFile)file).getImportList())) { return "imports"; } else { diff --git a/java/java-impl/src/com/intellij/codeInsight/folding/impl/actions/CollapseBlockAction.java b/java/java-impl/src/com/intellij/codeInsight/folding/impl/actions/CollapseBlockAction.java index ee56654784f4..1bc86f48ff47 100644 --- a/java/java-impl/src/com/intellij/codeInsight/folding/impl/actions/CollapseBlockAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/folding/impl/actions/CollapseBlockAction.java @@ -18,11 +18,13 @@ package com.intellij.codeInsight.folding.impl.actions; import com.intellij.codeInsight.CodeInsightActionHandler; import com.intellij.codeInsight.actions.BaseCodeInsightAction; import com.intellij.codeInsight.folding.impl.CollapseBlockHandler; +import org.jetbrains.annotations.NotNull; /** * @author ven */ public class CollapseBlockAction extends BaseCodeInsightAction { + @NotNull @Override protected CodeInsightActionHandler getHandler() { return new CollapseBlockHandler (); diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java index 115545a38828..8a2fa775a35a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java @@ -61,6 +61,7 @@ import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.*; import com.intellij.util.ArrayUtil; +import com.intellij.util.Consumer; import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; @@ -95,7 +96,7 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { * @return list of method prototypes */ @NotNull - public static Collection<PsiMethod> overrideOrImplementMethod(PsiClass aClass, PsiMethod method, boolean toCopyJavaDoc) throws IncorrectOperationException { + public static List<PsiMethod> overrideOrImplementMethod(PsiClass aClass, PsiMethod method, boolean toCopyJavaDoc) throws IncorrectOperationException { final PsiClass containingClass = method.getContainingClass(); LOG.assertTrue(containingClass != null); PsiSubstitutor substitutor = aClass.isInheritor(containingClass, true) @@ -126,11 +127,18 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { } @NotNull - private static Collection<PsiMethod> overrideOrImplementMethod(PsiClass aClass, + private static List<PsiMethod> overrideOrImplementMethod(PsiClass aClass, PsiMethod method, PsiSubstitutor substitutor, boolean toCopyJavaDoc, boolean insertOverrideIfPossible) throws IncorrectOperationException { + return overrideOrImplementMethod(aClass, method, substitutor, createDefaultDecorator(aClass, method, toCopyJavaDoc, insertOverrideIfPossible)); + } + + public static List<PsiMethod> overrideOrImplementMethod(PsiClass aClass, + PsiMethod method, + PsiSubstitutor substitutor, + Consumer<PsiMethod> decorator) throws IncorrectOperationException { if (!method.isValid() || !substitutor.isValid()) return Collections.emptyList(); List<PsiMethod> results = new ArrayList<PsiMethod>(); @@ -141,13 +149,14 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { } else { for (PsiMethod prototype : prototypes) { - results.add(decorateMethod(aClass, method, toCopyJavaDoc, insertOverrideIfPossible, prototype)); + decorator.consume(prototype); + results.add(prototype); } } } if (results.isEmpty()) { PsiMethod method1 = GenerateMembersUtil.substituteGenericMethod(method, substitutor, aClass); - + PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); PsiMethod result = (PsiMethod)factory.createClass("Dummy").add(method1); if (PsiUtil.isAnnotationMethod(result)) { @@ -161,7 +170,8 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { defaultValue.getParent().deleteChildRange(defaultKeyword, defaultValue); } } - results.add(decorateMethod(aClass, method, toCopyJavaDoc, insertOverrideIfPossible, result)); + decorator.consume(result); + results.add(result); } for (Iterator<PsiMethod> iterator = results.iterator(); iterator.hasNext();) { @@ -173,6 +183,18 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { return results; } + public static Consumer<PsiMethod> createDefaultDecorator(final PsiClass aClass, + final PsiMethod method, + final boolean toCopyJavaDoc, + final boolean insertOverrideIfPossible) { + return new Consumer<PsiMethod>() { + @Override + public void consume(PsiMethod result) { + decorateMethod(aClass, method, toCopyJavaDoc, insertOverrideIfPossible, result); + } + }; + } + private static PsiMethod decorateMethod(PsiClass aClass, PsiMethod method, boolean toCopyJavaDoc, @@ -182,10 +204,7 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { PsiUtil.setModifierProperty(result, PsiModifier.NATIVE, false); if (!toCopyJavaDoc){ - PsiDocComment comment = result.getDocComment(); - if (comment != null){ - comment.delete(); - } + deleteDocComment(result); } //method type params are not allowed when overriding from raw type @@ -231,6 +250,13 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { return result; } + public static void deleteDocComment(PsiMethod result) { + PsiDocComment comment = result.getDocComment(); + if (comment != null){ + comment.delete(); + } + } + public static void annotateOnOverrideImplement(PsiMethod method, PsiClass targetClass, PsiMethod overridden) { annotateOnOverrideImplement(method, targetClass, overridden, CodeStyleSettingsManager.getSettings(method.getProject()).INSERT_OVERRIDE_ANNOTATION); diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallAction.java b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallAction.java index 550b621eee87..62881172e102 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallAction.java @@ -22,15 +22,17 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiJavaFile; import com.intellij.psi.PsiMethod; +import org.jetbrains.annotations.NotNull; public class GenerateSuperMethodCallAction extends BaseCodeInsightAction { + @NotNull @Override protected CodeInsightActionHandler getHandler() { return new GenerateSuperMethodCallHandler(); } @Override - protected boolean isValidForFile(Project project, Editor editor, final PsiFile file) { + protected boolean isValidForFile(@NotNull Project project, @NotNull Editor editor, @NotNull final PsiFile file) { if (!(file instanceof PsiJavaFile)) { return false; } diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseMoveInitializerToMethodAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseMoveInitializerToMethodAction.java index 0f9081ceb6cb..549a47fb208d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseMoveInitializerToMethodAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseMoveInitializerToMethodAction.java @@ -79,6 +79,7 @@ public abstract class BaseMoveInitializerToMethodAction extends PsiElementBaseIn final Collection<PsiMethod> methodsToAddInitialization = getOrCreateMethods(project, editor, element.getContainingFile(), aClass); + if (methodsToAddInitialization.isEmpty()) return; final List<PsiExpressionStatement> assignments = addFieldAssignments(field, methodsToAddInitialization); field.getInitializer().delete(); diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SplitIfAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SplitIfAction.java index 7765a299a6a8..c6a6d536fe9a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SplitIfAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SplitIfAction.java @@ -26,6 +26,7 @@ import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.util.RefactoringUtil; +import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -125,25 +126,28 @@ public class SplitIfAction extends PsiElementBaseIntentionAction { } private static PsiExpression getROperands(PsiPolyadicExpression expression, PsiJavaToken separator) throws IncorrectOperationException { - PsiElement next = PsiTreeUtil.skipSiblingsForward(separator.getNextSibling(), PsiWhiteSpace.class, PsiComment.class); + PsiElement next = PsiTreeUtil.skipSiblingsForward(separator, PsiWhiteSpace.class, PsiComment.class); + final int offsetInParent; if (next == null) { - throw new IncorrectOperationException("Unable to split '"+expression.getText()+"' at '"+separator+"' (offset "+separator.getStartOffsetInParent()+")"); + offsetInParent = separator.getStartOffsetInParent() + separator.getTextLength(); + } else { + offsetInParent = next.getStartOffsetInParent(); } PsiElementFactory factory = JavaPsiFacade.getInstance(expression.getProject()).getElementFactory(); - String rOperands = expression.getText().substring(next.getStartOffsetInParent()); + String rOperands = expression.getText().substring(offsetInParent); return factory.createExpressionFromText(rOperands, expression.getParent()); } private static PsiExpression getLOperands(PsiPolyadicExpression expression, PsiJavaToken separator) throws IncorrectOperationException { - PsiElement next = separator; - if (next.getPrevSibling() instanceof PsiWhiteSpace) next = next.getPrevSibling(); - if (next == null) { + PsiElement prev = separator; + if (prev.getPrevSibling() instanceof PsiWhiteSpace) prev = prev.getPrevSibling(); + if (prev == null) { throw new IncorrectOperationException("Unable to split '"+expression.getText()+"' left to '"+separator+"' (offset "+separator.getStartOffsetInParent()+")"); } PsiElementFactory factory = JavaPsiFacade.getInstance(expression.getProject()).getElementFactory(); - String rOperands = expression.getText().substring(0, next.getStartOffsetInParent()); + String rOperands = expression.getText().substring(0, prev.getStartOffsetInParent()); return factory.createExpressionFromText(rOperands, expression.getParent()); } diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java index 11cfe66ef6c0..cba613755b46 100644 --- a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java +++ b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java @@ -27,7 +27,6 @@ import com.intellij.psi.*; import com.intellij.psi.impl.DebugUtil; import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.impl.source.PsiClassReferenceType; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -55,6 +54,7 @@ public class PsiTypeLookupItem extends LookupItem { private final int myBracketsCount; private boolean myIndicateAnonymous; private final InsertHandler<PsiTypeLookupItem> myImportFixer; + private boolean myAddArrayInitializer; private PsiTypeLookupItem(Object o, @NotNull @NonNls String lookupString, boolean diamond, int bracketsCount, InsertHandler<PsiTypeLookupItem> fixer) { super(o, lookupString); @@ -84,7 +84,17 @@ public class PsiTypeLookupItem extends LookupItem { @Override public boolean equals(final Object o) { - return super.equals(o) && o instanceof PsiTypeLookupItem && getBracketsCount() == ((PsiTypeLookupItem) o).getBracketsCount(); + return super.equals(o) && o instanceof PsiTypeLookupItem && + getBracketsCount() == ((PsiTypeLookupItem) o).getBracketsCount() && + myAddArrayInitializer == ((PsiTypeLookupItem) o).myAddArrayInitializer; + } + + public boolean isAddArrayInitializer() { + return myAddArrayInitializer; + } + + public void setAddArrayInitializer() { + myAddArrayInitializer = true; } @Override @@ -93,7 +103,6 @@ public class PsiTypeLookupItem extends LookupItem { PsiElement position = context.getFile().findElementAt(context.getStartOffset()); assert position != null; - boolean addBraces = shouldAddBraces(position); int genericsStart = context.getTailOffset(); context.getDocument().insertString(genericsStart, JavaCompletionUtil.escapeXmlIfNeeded(context, calcGenerics(position, context))); JavaCompletionUtil.shortenReference(context.getFile(), genericsStart - 1); @@ -102,7 +111,7 @@ public class PsiTypeLookupItem extends LookupItem { String braces = StringUtil.repeat("[]", getBracketsCount()); Editor editor = context.getEditor(); if (!braces.isEmpty()) { - if (LookupEvent.isSpecialCompletionChar(context.getCompletionChar()) && addBraces) { + if (myAddArrayInitializer) { context.getDocument().insertString(tail, braces + "{}"); editor.getCaretModel().moveToOffset(tail + braces.length() + 1); } else { @@ -125,14 +134,6 @@ public class PsiTypeLookupItem extends LookupItem { } } - private static boolean shouldAddBraces(PsiElement position) { - if (!JavaCompletionContributor.isInJavaContext(position) || !JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) { - return false; - } - PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(position, PsiNewExpression.class); - return newExpression != null && newExpression.getParent() instanceof PsiExpressionList; - } - public String calcGenerics(@NotNull PsiElement context, InsertionContext insertionContext) { if (insertionContext.getCompletionChar() == '<') { return ""; diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java b/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java index 7f47e02399f3..9fa4834de1c5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java +++ b/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java @@ -4,6 +4,8 @@ import com.intellij.codeInsight.AutoPopupController; import com.intellij.codeInsight.TailType; import com.intellij.codeInsight.completion.*; import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.RangeMarker; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.impl.source.PostprocessReformattingAspect; @@ -84,17 +86,24 @@ public class VariableLookupItem extends LookupItem<PsiVariable> implements Typed public void handleInsert(InsertionContext context) { PsiVariable variable = getObject(); - context.getDocument().replaceString(context.getStartOffset(), context.getTailOffset(), variable.getName()); + Document document = context.getDocument(); + document.replaceString(context.getStartOffset(), context.getTailOffset(), variable.getName()); context.commitDocument(); if (variable instanceof PsiField) { if (willBeImported()) { + RangeMarker toDelete = JavaCompletionUtil.insertTemporary(context.getTailOffset(), document, " "); + context.commitDocument(); final PsiReferenceExpression ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiReferenceExpression.class, false); if (ref != null) { ref.bindToElementViaStaticImport(((PsiField)variable).getContainingClass()); PostprocessReformattingAspect.getInstance(ref.getProject()).doPostponedFormatting(); } + if (toDelete.isValid()) { + document.deleteString(toDelete.getStartOffset(), toDelete.getEndOffset()); + } + context.commitDocument(); } else if (shouldQualify((PsiField)variable, context)) { qualifyFieldReference(context, (PsiField)variable); @@ -127,7 +136,7 @@ public class VariableLookupItem extends LookupItem<PsiVariable> implements Typed context.setAddCompletionChar(false); if (ref != null) { FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EXCLAMATION_FINISH); - context.getDocument().insertString(ref.getTextRange().getStartOffset(), "!"); + document.insertString(ref.getTextRange().getStartOffset(), "!"); } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/navigation/JavaMethodNavigationOffsetProvider.java b/java/java-impl/src/com/intellij/codeInsight/navigation/JavaMethodNavigationOffsetProvider.java index ee84ce5c6c4a..eb803e6704d0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/navigation/JavaMethodNavigationOffsetProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/navigation/JavaMethodNavigationOffsetProvider.java @@ -38,7 +38,7 @@ public class JavaMethodNavigationOffsetProvider implements MethodNavigationOffse private static void addNavigationElements(ArrayList<PsiElement> array, PsiElement element) { PsiElement[] children = element.getChildren(); for (PsiElement child : children) { - if (child instanceof PsiMethod || child instanceof PsiClass) { + if (child instanceof PsiMethod || child instanceof PsiClass || child instanceof PsiField) { array.add(child); addNavigationElements(array, child); } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java b/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java index b5c1b669928e..22029d8a3ad5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java @@ -25,6 +25,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiVariable; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.LinkedList; @@ -54,6 +55,12 @@ public class SuggestVariableNameMacro extends Macro { return new TextResult(names[0]); } + @Nullable + @Override + public Result calculateQuickResult(@NotNull Expression[] params, ExpressionContext context) { + return calculateResult(params, context); + } + @Override public LookupElement[] calculateLookupItems(@NotNull Expression[] params, final ExpressionContext context) { String[] names = getNames(context); diff --git a/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java b/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java index 75116480fdf0..1c54bff2716e 100644 --- a/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java @@ -205,34 +205,42 @@ public class LambdaCanBeMethReferenceInspection extends BaseJavaLocalInspectionT final String methodReferenceName = methodExpression.getReferenceName(); if (qualifierExpression != null) { boolean isReceiverType = PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, containingClass, psiMethod); - methodRefText = (isReceiverType ? containingClass.getQualifiedName() : qualifierExpression.getText()) + "::" + ((PsiMethodCallExpression)element).getTypeArgumentList().getText() + methodReferenceName; + methodRefText = (isReceiverType ? getClassReferenceName(containingClass) : qualifierExpression.getText()) + "::" + ((PsiMethodCallExpression)element).getTypeArgumentList().getText() + methodReferenceName; } else { methodRefText = - (psiMethod.hasModifierProperty(PsiModifier.STATIC) ? containingClass.getQualifiedName() : "this") + "::" + methodReferenceName; + (psiMethod.hasModifierProperty(PsiModifier.STATIC) ? getClassReferenceName(containingClass) : "this") + "::" + methodReferenceName; } } else if (element instanceof PsiNewExpression) { final PsiMethod constructor = ((PsiNewExpression)element).resolveConstructor(); + PsiClass containingClass = null; if (constructor != null) { - final PsiClass containingClass = constructor.getContainingClass(); + containingClass = constructor.getContainingClass(); LOG.assertTrue(containingClass != null); - methodRefText = containingClass.getQualifiedName() + "::new"; } else { final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)element).getClassOrAnonymousClassReference(); if (classReference != null) { final JavaResolveResult resolve = classReference.advancedResolve(false); - final PsiElement containingClass = resolve.getElement(); - if (containingClass instanceof PsiClass) { - methodRefText = ((PsiClass)containingClass).getQualifiedName() + "::new"; + final PsiElement resolveElement = resolve.getElement(); + if (resolveElement instanceof PsiClass) { + containingClass = (PsiClass)resolveElement; } } } + if (containingClass != null) { + methodRefText = getClassReferenceName(containingClass) + "::new"; + } } return methodRefText; } + private static String getClassReferenceName(PsiClass containingClass) { + final String qualifiedName = containingClass.getQualifiedName(); + return qualifiedName != null ? qualifiedName : containingClass.getName(); + } + private static class ReplaceWithMethodRefFix implements LocalQuickFix { @NotNull @Override @@ -251,12 +259,21 @@ public class LambdaCanBeMethReferenceInspection extends BaseJavaLocalInspectionT final PsiElement element = descriptor.getPsiElement(); final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class); if (lambdaExpression == null) return; - final String methodRefText = createMethodReferenceText(element, lambdaExpression.getFunctionalInterfaceType()); + final PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType(); + final String methodRefText = createMethodReferenceText(element, functionalInterfaceType); if (methodRefText != null) { + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); final PsiExpression psiExpression = - JavaPsiFacade.getElementFactory(project).createExpressionFromText(methodRefText, lambdaExpression); - JavaCodeStyleManager.getInstance(project).shortenClassReferences(lambdaExpression.replace(psiExpression)); + factory.createExpressionFromText(methodRefText, lambdaExpression); + PsiElement replace = lambdaExpression.replace(psiExpression); + if (((PsiMethodReferenceExpression)replace).getFunctionalInterfaceType() == null) { //ambiguity + final PsiTypeCastExpression cast = (PsiTypeCastExpression)factory.createExpressionFromText("(A)a", replace); + cast.getCastType().replace(factory.createTypeElement(functionalInterfaceType)); + cast.getOperand().replace(replace); + replace = replace.replace(cast); + } + JavaCodeStyleManager.getInstance(project).shortenClassReferences(replace); } } } diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java b/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java index 3ee49d07d7b9..ee5e883e3a2d 100644 --- a/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java @@ -107,10 +107,12 @@ public class RedundantSuppressInspection extends GlobalInspectionTool{ @Nullable private CommonProblemDescriptor[] checkElement(RefClass refEntity, InspectionManager manager, final Project project) { - return checkElement(refEntity.getElement(), manager, project); + final PsiClass psiClass = refEntity.getElement(); + if (psiClass == null) return null; + return checkElement(psiClass, manager, project); } - public CommonProblemDescriptor[] checkElement(final PsiElement psiElement, InspectionManager manager, Project project) { + public CommonProblemDescriptor[] checkElement(@NotNull final PsiElement psiElement, InspectionManager manager, Project project) { final Map<PsiElement, Collection<String>> suppressedScopes = new THashMap<PsiElement, Collection<String>>(); psiElement.accept(new JavaRecursiveElementWalkingVisitor() { @Override public void visitModifierList(PsiModifierList list) { diff --git a/java/java-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java b/java/java-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java index d08ba72cc81f..cf08dacf7045 100644 --- a/java/java-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java +++ b/java/java-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java @@ -49,7 +49,15 @@ public class ReplaceWithTernaryOperatorFix implements LocalQuickFix { @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - final PsiElement element = descriptor.getPsiElement(); + PsiElement element = descriptor.getPsiElement(); + while (true) { + PsiElement parent = element.getParent(); + if (parent instanceof PsiReferenceExpression || parent instanceof PsiMethodCallExpression) { + element = parent; + } else { + break; + } + } if (!(element instanceof PsiExpression)) { return; } diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index 992969dda54e..e3170217680f 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -21,7 +21,9 @@ import com.intellij.codeInspection.dataFlow.value.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; @@ -31,7 +33,14 @@ import com.intellij.util.containers.Stack; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static com.intellij.psi.CommonClassNames.JAVA_LANG_ERROR; +import static com.intellij.psi.CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION; +import static com.intellij.psi.CommonClassNames.JAVA_LANG_THROWABLE; class ControlFlowAnalyzer extends JavaElementVisitor { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer"); @@ -45,7 +54,8 @@ class ControlFlowAnalyzer extends JavaElementVisitor { private int myPassNumber; private Set<DfaVariableValue> myFields; private Stack<CatchDescriptor> myCatchStack; - private PsiType myRuntimeException; + private DfaValue myRuntimeException; + private DfaValue myError; ControlFlowAnalyzer(final DfaValueFactory valueFactory) { myFactory = valueFactory; @@ -54,7 +64,10 @@ class ControlFlowAnalyzer extends JavaElementVisitor { public ControlFlow buildControlFlow(PsiElement codeFragment) { if (codeFragment == null) return null; - myRuntimeException = PsiType.getJavaLangRuntimeException(codeFragment.getManager(), codeFragment.getResolveScope()); + PsiManager manager = codeFragment.getManager(); + GlobalSearchScope scope = codeFragment.getResolveScope(); + myRuntimeException = myFactory.getNotNullFactory().create(PsiType.getJavaLangRuntimeException(manager, scope)); + myError = myFactory.getNotNullFactory().create(PsiType.getJavaLangError(manager, scope)); myFields = new HashSet<DfaVariableValue>(); myCatchStack = new Stack<CatchDescriptor>(); myPassNumber = 1; @@ -638,10 +651,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { continue; } - PsiType type = cd.getType(); - if (type instanceof PsiDisjunctionType) { - type = ((PsiDisjunctionType)type).getLeastUpperBound(); - } + PsiType type = cd.getLubType(); if (type instanceof PsiClassType && ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType)type)) { addConditionalRuntimeThrow(cd, true); break; @@ -655,8 +665,22 @@ class ControlFlowAnalyzer extends JavaElementVisitor { addInstruction(branch); addInstruction(new EmptyStackInstruction()); if (forCatch) { - addInstruction(new PushInstruction(myFactory.getNotNullFactory().create(myRuntimeException), null)); - addGotoCatch(cd); + PsiType type = cd.getLubType(); + boolean isRuntime = InheritanceUtil.isInheritor(type, JAVA_LANG_RUNTIME_EXCEPTION) || ExceptionUtil.isGeneralExceptionType(type); + boolean isError = InheritanceUtil.isInheritor(type, JAVA_LANG_ERROR) || type.equalsToText(JAVA_LANG_THROWABLE); + if (isRuntime != isError) { + addInstruction(new PushInstruction(isRuntime ? myRuntimeException : myError, null)); + addGotoCatch(cd); + } else { + pushUnknown(); + final ConditionalGotoInstruction branch2 = new ConditionalGotoInstruction(-1, false, null); + addInstruction(branch2); + addInstruction(new PushInstruction(myError, null)); + addGotoCatch(cd); + branch2.setOffset(myCurrentFlow.getInstructionCount()); + addInstruction(new PushInstruction(myRuntimeException, null)); + addGotoCatch(cd); + } } else { addInstruction(new GosubInstruction(cd.getJumpOffset(this))); @@ -755,6 +779,14 @@ class ControlFlowAnalyzer extends JavaElementVisitor { return myType; } + PsiType getLubType() { + PsiType type = myType; + if (type instanceof PsiDisjunctionType) { + return ((PsiDisjunctionType)type).getLeastUpperBound(); + } + return type; + } + public boolean isFinally() { return myIsFinally; } @@ -1222,7 +1254,11 @@ class ControlFlowAnalyzer extends JavaElementVisitor { } } - addInstruction(new MethodCallInstruction(expression, createChainedVariableValue(expression))); + MethodCallInstruction callInstruction = new MethodCallInstruction(expression, createChainedVariableValue(expression)); + if (!DfaValueFactory.isEffectivelyUnqualified(methodExpression)) { + callInstruction.setShouldFlushFields(false); + } + addInstruction(callInstruction); if (!myCatchStack.isEmpty()) { addMethodThrows(expression.resolveMethod()); @@ -1560,7 +1596,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { return myFactory.getVarFactory().createVariableValue(var, refExpr.getType(), false, null, isCall); } - if (DfaVariableState.isFinalField(var)) { + if (DfaUtil.isFinalField(var) || DfaUtil.isPlainMutableField(var)) { DfaVariableValue qualifierValue = createChainedVariableValue(qualifier); if (qualifierValue != null) { return myFactory.getVarFactory().createVariableValue(var, refExpr.getType(), false, qualifierValue, isCall || qualifierValue.isViaMethods()); @@ -1576,7 +1612,10 @@ class ControlFlowAnalyzer extends JavaElementVisitor { return (PsiVariable)target; } if (target instanceof PsiMethod) { - return PropertyUtils.getSimplyReturnedField((PsiMethod)target, PropertyUtils.getSingleReturnValue((PsiMethod)target)); + PsiMethod method = (PsiMethod)target; + if (PropertyUtils.isSimpleGetter(method)) { + return PropertyUtils.getSimplyReturnedField(method, PropertyUtils.getSingleReturnValue(method)); + } } return null; } diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java index e8b74efd73d0..87e0d2dad351 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java @@ -28,7 +28,9 @@ import com.intellij.codeInspection.dataFlow.value.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.*; +import com.intellij.psi.JavaTokenType; +import com.intellij.psi.PsiPrimitiveType; +import com.intellij.psi.PsiType; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; @@ -77,15 +79,8 @@ public class DfaMemoryStateImpl implements DfaMemoryState { newState.myEqClasses.add(aClass != null ? new SortedIntSet(aClass.toNativeArray()) : null); } - try { - for (Object o : myVariableStates.keySet()) { - DfaVariableValue dfaVariableValue = (DfaVariableValue)o; - DfaVariableState clone = (DfaVariableState)myVariableStates.get(dfaVariableValue).clone(); - newState.myVariableStates.put(dfaVariableValue, clone); - } - } - catch (CloneNotSupportedException e) { - LOG.error(e); + for (DfaVariableValue dfaVariableValue : myVariableStates.keySet()) { + newState.myVariableStates.put(dfaVariableValue, myVariableStates.get(dfaVariableValue).clone()); } return newState; } @@ -280,13 +275,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { applyCondition(dfaEqual); if (value instanceof DfaVariableValue) { - try { - DfaVariableState newState = (DfaVariableState)getVariableState((DfaVariableValue)value).clone(); - myVariableStates.put(var, newState); - } - catch (CloneNotSupportedException e) { - LOG.error(e); - } + myVariableStates.put(var, getVariableState((DfaVariableValue)value).clone()); } } @@ -782,18 +771,15 @@ public class DfaMemoryStateImpl implements DfaMemoryState { public void flushFields(DataFlowRunner runner) { for (DfaVariableValue field : runner.getFields()) { if (myVariableStates.containsKey(field) || getEqClassIndex(field) >= 0) { - flushVariable(field); - getVariableState(field).setNullable(false); + if (!DfaUtil.isFinalField(field.getPsiVariable())) { + flushWithDependencies(field); + getVariableState(field).setNullable(false); + } } } } public void flushVariable(@NotNull DfaVariableValue variable) { - PsiVariable psiVariable = variable.getPsiVariable(); - if (DfaVariableState.isFinalField(psiVariable)) { - return; - } - flushWithDependencies(variable); } diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java index 065464ff47b5..69c7b05f8e2b 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java @@ -21,6 +21,7 @@ import com.intellij.codeInspection.dataFlow.instructions.Instruction; import com.intellij.codeInspection.dataFlow.instructions.PushInstruction; import com.intellij.codeInspection.dataFlow.value.DfaValue; import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; +import com.intellij.codeInspection.nullable.NullableStuffInspection; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.MultiValuesMap; import com.intellij.openapi.util.Ref; @@ -85,17 +86,17 @@ public class DfaUtil { return expressions == null ? Collections.<PsiExpression>emptyList() : expressions; } - @Nullable - static Boolean getElementNullability(@Nullable PsiType resultType, @Nullable PsiModifierListOwner owner) { + @NotNull + public static Nullness getElementNullability(@Nullable PsiType resultType, @Nullable PsiModifierListOwner owner) { if (owner == null) { - return null; + return Nullness.UNKNOWN; } if (NullableNotNullManager.isNullable(owner)) { - return Boolean.TRUE; + return Nullness.NULLABLE; } if (NullableNotNullManager.isNotNull(owner)) { - return Boolean.FALSE; + return Nullness.NOT_NULL; } if (resultType != null) { @@ -103,19 +104,51 @@ public class DfaUtil { for (PsiAnnotation annotation : resultType.getAnnotations()) { String qualifiedName = annotation.getQualifiedName(); if (nnn.getNullables().contains(qualifiedName)) { - return Boolean.TRUE; + return Nullness.NULLABLE; } if (nnn.getNotNulls().contains(qualifiedName)) { - return Boolean.FALSE; + return Nullness.NOT_NULL; } } } - return null; + return Nullness.UNKNOWN; + } + + public static boolean isNullableInitialized(PsiVariable var, boolean nullable) { + if (!isFinalField(var)) { + return false; + } + + List<PsiExpression> initializers = NullableStuffInspection.findAllConstructorInitializers((PsiField)var); + if (initializers.isEmpty()) { + return false; + } + + for (PsiExpression expression : initializers) { + if (!(expression instanceof PsiReferenceExpression)) { + return false; + } + PsiElement target = ((PsiReferenceExpression)expression).resolve(); + if (!(target instanceof PsiParameter)) { + return false; + } + if (nullable && NullableNotNullManager.isNullable((PsiParameter)target)) { + return true; + } + if (!nullable && !NullableNotNullManager.isNotNull((PsiParameter)target)) { + return false; + } + } + return !nullable; + } + + public static boolean isPlainMutableField(PsiVariable var) { + return !var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && !var.hasModifierProperty(PsiModifier.VOLATILE) && var instanceof PsiField; } - public static enum Nullness { - NOT_NULL,NULL,UNKNOWN + public static boolean isFinalField(PsiVariable var) { + return var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && var instanceof PsiField; } @NotNull @@ -131,7 +164,7 @@ public class DfaUtil { if (result != RunnerResult.OK) { return Nullness.UNKNOWN; } - if (visitor.myNulls.contains(variable) && !visitor.myNotNulls.contains(variable)) return Nullness.NULL; + if (visitor.myNulls.contains(variable) && !visitor.myNotNulls.contains(variable)) return Nullness.NULLABLE; if (visitor.myNotNulls.contains(variable) && !visitor.myNulls.contains(variable)) return Nullness.NOT_NULL; return Nullness.UNKNOWN; } diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java index 02e841c89132..7c86f7f4e27b 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java @@ -24,11 +24,9 @@ */ package com.intellij.codeInspection.dataFlow; -import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.codeInspection.dataFlow.value.DfaTypeValue; import com.intellij.codeInspection.dataFlow.value.DfaValue; import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; -import com.intellij.codeInspection.nullable.NullableStuffInspection; import com.intellij.psi.*; import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; @@ -37,65 +35,28 @@ import org.jetbrains.annotations.Nullable; import java.util.HashSet; import java.util.Iterator; -import java.util.List; import java.util.Set; public class DfaVariableState implements Cloneable { private final Set<DfaTypeValue> myInstanceofValues; private final Set<DfaTypeValue> myNotInstanceofValues; - private boolean myNullable = false; - private final boolean myVariableIsDeclaredNotNull; + private Nullness myNullability; public DfaVariableState(@NotNull DfaVariableValue dfaVar) { myInstanceofValues = new HashSet<DfaTypeValue>(); myNotInstanceofValues = new HashSet<DfaTypeValue>(); - PsiVariable var = dfaVar.getPsiVariable(); - Boolean nullability = DfaUtil.getElementNullability(dfaVar.getVariableType(), var); - myNullable = nullability == Boolean.TRUE || var != null && isNullableInitialized(var, true); - myVariableIsDeclaredNotNull = nullability == Boolean.FALSE || var != null && isNullableInitialized(var, false); + + myNullability = dfaVar.getInherentNullability(); } protected DfaVariableState(final DfaVariableState toClone) { myInstanceofValues = new THashSet<DfaTypeValue>(toClone.myInstanceofValues); myNotInstanceofValues = new THashSet<DfaTypeValue>(toClone.myNotInstanceofValues); - myNullable = toClone.myNullable; - myVariableIsDeclaredNotNull = toClone.myVariableIsDeclaredNotNull; - } - - private static boolean isNullableInitialized(PsiVariable var, boolean nullable) { - if (!isFinalField(var)) { - return false; - } - - List<PsiExpression> initializers = NullableStuffInspection.findAllConstructorInitializers((PsiField)var); - if (initializers.isEmpty()) { - return false; - } - - for (PsiExpression expression : initializers) { - if (!(expression instanceof PsiReferenceExpression)) { - return false; - } - PsiElement target = ((PsiReferenceExpression)expression).resolve(); - if (!(target instanceof PsiParameter)) { - return false; - } - if (nullable && NullableNotNullManager.isNullable((PsiParameter)target)) { - return true; - } - if (!nullable && !NullableNotNullManager.isNotNull((PsiParameter)target)) { - return false; - } - } - return !nullable; - } - - public static boolean isFinalField(PsiVariable var) { - return var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && var instanceof PsiField; + myNullability = toClone.myNullability; } public boolean isNullable() { - return myNullable; + return myNullability == Nullness.NULLABLE; } private boolean checkInstanceofValue(DfaTypeValue dfaType) { @@ -113,7 +74,9 @@ public class DfaVariableState implements Cloneable { } public boolean setInstanceofValue(DfaTypeValue dfaType) { - myNullable |= dfaType.isNullable(); + if (dfaType.isNullable()) { + myNullability = Nullness.NULLABLE; + } if (dfaType.getType() instanceof PsiPrimitiveType) return true; @@ -146,10 +109,10 @@ public class DfaVariableState implements Cloneable { DfaVariableState aState = (DfaVariableState) obj; return myInstanceofValues.equals(aState.myInstanceofValues) && myNotInstanceofValues.equals(aState.myNotInstanceofValues) && - myNullable == aState.myNullable; + myNullability == aState.myNullability; } - protected Object clone() throws CloneNotSupportedException { + protected DfaVariableState clone() { return new DfaVariableState(this); } @@ -169,16 +132,18 @@ public class DfaVariableState implements Cloneable { buf.append("{").append(dfaTypeValue).append("}"); if (iterator.hasNext()) buf.append(", "); } - buf.append(", nullable=").append(myNullable); + buf.append(", nullable=").append(myNullability); return buf.toString(); } public boolean isNotNull() { - return myVariableIsDeclaredNotNull; + return myNullability == Nullness.NOT_NULL; } public void setNullable(final boolean nullable) { - myNullable = nullable; + if (myNullability != Nullness.NOT_NULL) { + myNullability = nullable ? Nullness.NULLABLE : Nullness.UNKNOWN; + } } public void setValue(DfaValue value) { diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/Nullness.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/Nullness.java new file mode 100644 index 000000000000..3dd099b0c1d3 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/Nullness.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2013 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.codeInspection.dataFlow; + +/** +* @author cdr +*/ +public enum Nullness { + NOT_NULL, NULLABLE,UNKNOWN +} diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java index a216be6f3cb0..54df852bfbab 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java @@ -40,26 +40,26 @@ public class StandardInstructionVisitor extends InstructionVisitor { private final Set<BinopInstruction> myCanBeNullInInstanceof = new THashSet<BinopInstruction>(); private final Set<PsiElement> myNotToReportReachability = new THashSet<PsiElement>(); private final Set<InstanceofInstruction> myUsefulInstanceofs = new THashSet<InstanceofInstruction>(); - private final FactoryMap<MethodCallInstruction, Map<PsiExpression, Boolean>> myParametersNullability = new FactoryMap<MethodCallInstruction, Map<PsiExpression, Boolean>>() { + private final FactoryMap<MethodCallInstruction, Map<PsiExpression, Nullness>> myParametersNullability = new FactoryMap<MethodCallInstruction, Map<PsiExpression, Nullness>>() { @Nullable @Override - protected Map<PsiExpression, Boolean> create(MethodCallInstruction key) { + protected Map<PsiExpression, Nullness> create(MethodCallInstruction key) { return calcParameterNullability(key.getCallExpression()); } }; - private final FactoryMap<MethodCallInstruction, Boolean> myReturnTypeNullability = new FactoryMap<MethodCallInstruction, Boolean>() { + private final FactoryMap<MethodCallInstruction, Nullness> myReturnTypeNullability = new FactoryMap<MethodCallInstruction, Nullness>() { @Override - protected Boolean create(MethodCallInstruction key) { + protected Nullness create(MethodCallInstruction key) { final PsiCallExpression callExpression = key.getCallExpression(); if (callExpression instanceof PsiNewExpression) { - return Boolean.FALSE; + return Nullness.NOT_NULL; } return callExpression != null ? DfaUtil.getElementNullability(key.getResultType(), callExpression.resolveMethod()) : null; } }; - private static Map<PsiExpression, Boolean> calcParameterNullability(@Nullable PsiCallExpression callExpression) { + private static Map<PsiExpression, Nullness> calcParameterNullability(@Nullable PsiCallExpression callExpression) { PsiExpressionList argumentList = callExpression == null ? null : callExpression.getArgumentList(); if (argumentList != null) { JavaResolveResult result = callExpression.resolveMethodGenerics(); @@ -72,7 +72,7 @@ public class StandardInstructionVisitor extends InstructionVisitor { boolean varArg = isVarArgCall(method, substitutor, args, parameters); int checkedCount = Math.min(args.length, parameters.length) - (varArg ? 1 : 0); - Map<PsiExpression, Boolean> map = ContainerUtil.newHashMap(); + Map<PsiExpression, Nullness> map = ContainerUtil.newHashMap(); for (int i = 0; i < checkedCount; i++) { map.put(args[i], DfaUtil.getElementNullability(substitutor.substitute(parameters[i].getType()), parameters[i])); } @@ -112,7 +112,7 @@ public class StandardInstructionVisitor extends InstructionVisitor { if (dfaDest instanceof DfaVariableValue) { DfaVariableValue var = (DfaVariableValue) dfaDest; final PsiVariable psiVariable = var.getPsiVariable(); - if (DfaUtil.getElementNullability(var.getVariableType(), psiVariable) == Boolean.FALSE) { + if (DfaUtil.getElementNullability(var.getVariableType(), psiVariable) == Nullness.NOT_NULL) { if (!memState.applyNotNull(dfaSource)) { onAssigningToNotNullableVariable(instruction); } @@ -183,12 +183,12 @@ public class StandardInstructionVisitor extends InstructionVisitor { @Override public DfaInstructionState[] visitMethodCall(MethodCallInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) { final PsiExpression[] args = instruction.getArgs(); - Map<PsiExpression, Boolean> map = myParametersNullability.get(instruction); + Map<PsiExpression, Nullness> map = myParametersNullability.get(instruction); final DfaNotNullValue.Factory factory = runner.getFactory().getNotNullFactory(); for (int i = 0; i < args.length; i++) { final DfaValue arg = memState.pop(); PsiExpression expr = args[(args.length - i - 1)]; - if (map.get(expr) == Boolean.FALSE) { + if (map.get(expr) == Nullness.NOT_NULL) { if (!memState.applyNotNull(arg)) { onPassingNullParameter(expr); if (arg instanceof DfaVariableValue) { @@ -196,7 +196,7 @@ public class StandardInstructionVisitor extends InstructionVisitor { } } } - else if (map.containsKey(expr) && map.get(expr) == null && !memState.checkNotNullable(arg)) { + else if (map.get(expr) == Nullness.UNKNOWN && !memState.checkNotNullable(arg)) { onPassingNullParameterToNonAnnotated(runner, expr); } } @@ -230,8 +230,7 @@ public class StandardInstructionVisitor extends InstructionVisitor { final PsiType type = instruction.getResultType(); final MethodCallInstruction.MethodType methodType = instruction.getMethodType(); if (type != null && (type instanceof PsiClassType || type.getArrayDimensions() > 0)) { - @Nullable final Boolean nullability = myReturnTypeNullability.get(instruction); - return factory.createTypeValueWithNullability(type, nullability); + return factory.createTypeValueWithNullability(type, myReturnTypeNullability.get(instruction)); } if (methodType == MethodCallInstruction.MethodType.UNBOXING) { diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java index 8ae655d475b9..d715f7637c9d 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java @@ -67,7 +67,7 @@ public class ValuableDataFlowRunner extends AnnotationsAwareDataFlowRunner { return myValue; } - protected Object clone() throws CloneNotSupportedException { + protected ValuableDfaVariableState clone() { return new ValuableDfaVariableState(this); } } diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java index 22f98623447d..5f65a86caeed 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java @@ -72,6 +72,10 @@ public class MethodCallInstruction extends Instruction { } } + public void setShouldFlushFields(boolean shouldFlushFields) { + myShouldFlushFields = shouldFlushFields; + } + @Nullable public PsiType getResultType() { return myType; diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java index 83c9f5efaafb..d68679796fc4 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java @@ -24,9 +24,11 @@ */ package com.intellij.codeInspection.dataFlow.value; +import com.intellij.codeInspection.dataFlow.Nullness; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import com.intellij.psi.impl.JavaConstantExpressionEvaluator; +import com.intellij.psi.util.PsiTreeUtil; import gnu.trove.TIntObjectHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -49,8 +51,8 @@ public class DfaValueFactory { myRelationFactory = new DfaRelationValue.Factory(this); } - public DfaValue createTypeValueWithNullability(@Nullable PsiType type, @Nullable Boolean nullability) { - return nullability == Boolean.FALSE ? getNotNullFactory().create(type) : getTypeFactory().create(type, nullability == Boolean.TRUE); + public DfaValue createTypeValueWithNullability(@Nullable PsiType type, Nullness nullability) { + return nullability == Nullness.NOT_NULL ? getNotNullFactory().create(type) : getTypeFactory().create(type, nullability == Nullness.NULLABLE); } int createID() { @@ -133,7 +135,7 @@ public class DfaValueFactory { } } - if (isEffectivelyUnqualified(referenceExpression)) { + if (!variable.hasModifierProperty(PsiModifier.VOLATILE) && isEffectivelyUnqualified(referenceExpression)) { return getVarFactory().createVariableValue(variable, referenceExpression.getType(), false, null, false); } @@ -152,9 +154,20 @@ public class DfaValueFactory { return null; } - private static boolean isEffectivelyUnqualified(PsiReferenceExpression refExpression) { + public static boolean isEffectivelyUnqualified(PsiReferenceExpression refExpression) { PsiExpression qualifier = refExpression.getQualifierExpression(); - return qualifier == null || qualifier instanceof PsiThisExpression; + if (qualifier == null) { + return true; + } + if (qualifier instanceof PsiThisExpression){ + final PsiJavaCodeReferenceElement thisQualifier = ((PsiThisExpression)qualifier).getQualifier(); + if (thisQualifier == null) return true; + final PsiClass innerMostClass = PsiTreeUtil.getParentOfType(refExpression, PsiClass.class); + if (innerMostClass == thisQualifier.resolve()) { + return true; + } + } + return false; } private final DfaVariableValue.Factory myVarFactory; diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java index 1c0434dd6ddc..f56fcd8290eb 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java @@ -24,6 +24,8 @@ */ package com.intellij.codeInspection.dataFlow.value; +import com.intellij.codeInspection.dataFlow.DfaUtil; +import com.intellij.codeInspection.dataFlow.Nullness; import com.intellij.psi.PsiType; import com.intellij.psi.PsiVariable; import com.intellij.util.containers.HashMap; @@ -92,6 +94,7 @@ public class DfaVariableValue extends DfaValue { @Nullable private DfaVariableValue myQualifier; private boolean myIsNegated; private boolean myViaMethods; + private Nullness myInherentNullability; private DfaVariableValue(PsiVariable variable, PsiType varType, boolean isNegated, DfaValueFactory factory, @Nullable DfaVariableValue qualifier, boolean viaMethods) { super(factory); @@ -115,7 +118,7 @@ public class DfaVariableValue extends DfaValue { @Nullable public PsiType getVariableType() { - return myVariable == null ? null : myVariable.getType(); + return myVarType; } public boolean isNegated() { @@ -147,4 +150,25 @@ public class DfaVariableValue extends DfaValue { public boolean isViaMethods() { return myViaMethods; } + + public Nullness getInherentNullability() { + if (myInherentNullability != null) { + return myInherentNullability; + } + + PsiVariable var = getPsiVariable(); + Nullness nullability = DfaUtil.getElementNullability(getVariableType(), var); + if (nullability == Nullness.UNKNOWN && var != null) { + if (DfaUtil.isNullableInitialized(var, true)) { + nullability = Nullness.NULLABLE; + } else if (DfaUtil.isNullableInitialized(var, false)) { + nullability = Nullness.NOT_NULL; + } + } + + myInherentNullability = nullability; + + return nullability; + } + } diff --git a/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/FileHeaderChecker.java b/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/FileHeaderChecker.java index 309fefcddba8..6cc4a8cdc709 100644 --- a/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/FileHeaderChecker.java +++ b/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/FileHeaderChecker.java @@ -50,15 +50,12 @@ public class FileHeaderChecker { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.defaultFileTemplateUsage.FileHeaderChecker"); static ProblemDescriptor checkFileHeader(@NotNull final PsiFile file, final InspectionManager manager, boolean onTheFly) { - FileTemplate template = FileTemplateManager.getInstance().getDefaultTemplate(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME); TIntObjectHashMap<String> offsetToProperty = new TIntObjectHashMap<String>(); - String templateText = template.getText().trim(); - String regex = templateToRegex(templateText, offsetToProperty, file.getProject()); - regex = StringUtil.replace(regex, "with", "(?:with|by)"); - regex = ".*("+regex+").*"; - String fileText = file.getText(); - Pattern pattern = Pattern.compile(regex, Pattern.DOTALL); - Matcher matcher = pattern.matcher(fileText); + Pattern pattern = getTemplatePattern(FileTemplateManager.getInstance() + .getDefaultTemplate(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME), + file.getProject(), offsetToProperty + ); + Matcher matcher = pattern.matcher(file.getText()); if (matcher.matches()) { final int startOffset = matcher.start(1); final int endOffset = matcher.end(1); @@ -83,6 +80,14 @@ public class FileHeaderChecker { return null; } + public static Pattern getTemplatePattern(FileTemplate template, Project project, TIntObjectHashMap<String> offsetToProperty) { + String templateText = template.getText().trim(); + String regex = templateToRegex(templateText, offsetToProperty, project); + regex = StringUtil.replace(regex, "with", "(?:with|by)"); + regex = ".*("+regex+").*"; + return Pattern.compile(regex, Pattern.DOTALL); + } + private static Properties computeProperties(final Matcher matcher, final TIntObjectHashMap<String> offsetToProperty) { Properties properties = new Properties(FileTemplateManager.getInstance().getDefaultProperties()); int[] offsets = offsetToProperty.keys(); diff --git a/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java b/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java index 01fa24239dff..e65e8e4f2db5 100644 --- a/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java +++ b/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java @@ -135,7 +135,7 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext else if (entry instanceof LibraryOrderEntry) { final LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)entry; final Library library = libraryOrderEntry.getLibrary(); - if (library == null || library.getFiles(OrderRootType.CLASSES).length != library.getUrls(OrderRootType.CLASSES).length) { + if (library == null || library.getFiles(OrderRootType.CLASSES).length < library.getUrls(OrderRootType.CLASSES).length) { System.err.println(InspectionsBundle.message("offline.inspections.library.was.not.resolved", libraryOrderEntry.getPresentableName(), module.getName())); } diff --git a/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java b/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java index 66444fe29e9e..6923ccceb060 100644 --- a/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java @@ -466,7 +466,7 @@ public class NullableStuffInspection extends BaseLocalInspectionTool { } public static List<PsiExpression> findAllConstructorInitializers(PsiField field) { - final List<PsiExpression> result = ContainerUtil.createEmptyCOWList(); + final List<PsiExpression> result = ContainerUtil.createLockFreeCopyOnWriteList(); ContainerUtil.addIfNotNull(result, field.getInitializer()); PsiClass containingClass = field.getContainingClass(); diff --git a/java/java-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java b/java/java-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java index 29ae2b877666..6fd1d33a37f5 100644 --- a/java/java-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java @@ -21,9 +21,11 @@ import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.openapi.util.Comparing; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * User: anna @@ -120,7 +122,9 @@ public class SillyAssignmentInspection extends BaseJavaLocalInspectionTool { /** * @return true if both expressions resolve to the same variable/class or field in the same instance of the class */ - private static boolean sameInstanceReferences(PsiReferenceExpression lRef, PsiReferenceExpression rRef, PsiManager manager) { + private static boolean sameInstanceReferences(@Nullable PsiJavaCodeReferenceElement lRef, @Nullable PsiJavaCodeReferenceElement rRef, PsiManager manager) { + if (lRef == null && rRef == null) return true; + if (lRef == null || rRef == null) return false; PsiElement lResolved = lRef.resolve(); PsiElement rResolved = rRef.resolve(); if (!manager.areElementsEquivalent(lResolved, rResolved)) return false; @@ -128,15 +132,36 @@ public class SillyAssignmentInspection extends BaseJavaLocalInspectionTool { final PsiVariable variable = (PsiVariable)lResolved; if (variable.hasModifierProperty(PsiModifier.STATIC)) return true; - PsiExpression lQualifier = lRef.getQualifierExpression(); - PsiExpression rQualifier = rRef.getQualifierExpression(); - if (lQualifier instanceof PsiReferenceExpression && rQualifier instanceof PsiReferenceExpression) { - return sameInstanceReferences((PsiReferenceExpression)lQualifier, (PsiReferenceExpression)rQualifier, manager); + final PsiElement lQualifier = lRef.getQualifier(); + final PsiElement rQualifier = rRef.getQualifier(); + if (lQualifier instanceof PsiJavaCodeReferenceElement && rQualifier instanceof PsiJavaCodeReferenceElement) { + return sameInstanceReferences((PsiJavaCodeReferenceElement)lQualifier, (PsiJavaCodeReferenceElement)rQualifier, manager); } + if (Comparing.equal(lQualifier, rQualifier)) return true; boolean lThis = lQualifier == null || lQualifier instanceof PsiThisExpression || lQualifier instanceof PsiSuperExpression; boolean rThis = rQualifier == null || rQualifier instanceof PsiThisExpression || rQualifier instanceof PsiSuperExpression; - return lThis && rThis; + if (lThis && rThis) { + final PsiJavaCodeReferenceElement llQualifier = getQualifier(lQualifier); + final PsiJavaCodeReferenceElement rrQualifier = getQualifier(rQualifier); + return sameInstanceReferences(llQualifier, rrQualifier, manager); + } + return false; } + private static PsiJavaCodeReferenceElement getQualifier(PsiElement qualifier) { + if (qualifier instanceof PsiThisExpression) { + final PsiJavaCodeReferenceElement thisQualifier = ((PsiThisExpression)qualifier).getQualifier(); + if (thisQualifier != null) { + final PsiClass innerMostClass = PsiTreeUtil.getParentOfType(thisQualifier, PsiClass.class); + if (innerMostClass == thisQualifier.resolve()) { + return null; + } + } + return thisQualifier; + } else if (qualifier != null) { + return ((PsiSuperExpression)qualifier).getQualifier(); + } + return null; + } } diff --git a/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java index 833a7d06978b..684d99ca481b 100644 --- a/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java @@ -437,6 +437,7 @@ public class UncheckedWarningLocalInspection extends BaseJavaLocalInspectionTool public Boolean visitClassType(PsiClassType classType) { PsiClass psiClass = classType.resolve(); if (psiClass instanceof PsiTypeParameter) { + if (((PsiTypeParameter)psiClass).getOwner() == method) return Boolean.FALSE; return substitutor.substitute((PsiTypeParameter)psiClass) == null ? Boolean.TRUE : Boolean.FALSE; } PsiType[] parameters = classType.getParameters(); diff --git a/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java b/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java index 034f4a528aee..cec7c4a148b2 100644 --- a/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java +++ b/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java @@ -53,48 +53,48 @@ public class JavaFileHighlighter extends SyntaxHighlighterBase { ourMap1 = new HashMap<IElementType, TextAttributesKey>(); ourMap2 = new HashMap<IElementType, TextAttributesKey>(); - fillMap(ourMap1, ElementType.KEYWORD_BIT_SET, SyntaxHighlighterColors.KEYWORD); - fillMap(ourMap1, ElementType.LITERAL_BIT_SET, SyntaxHighlighterColors.KEYWORD); - fillMap(ourMap1, ElementType.OPERATION_BIT_SET, SyntaxHighlighterColors.OPERATION_SIGN); + fillMap(ourMap1, ElementType.KEYWORD_BIT_SET, JavaHighlightingColors .KEYWORD); + fillMap(ourMap1, ElementType.LITERAL_BIT_SET, JavaHighlightingColors.KEYWORD); + fillMap(ourMap1, ElementType.OPERATION_BIT_SET, JavaHighlightingColors.OPERATION_SIGN); for (IElementType type : JavaDocTokenType.ALL_JAVADOC_TOKENS.getTypes()) { - ourMap1.put(type, SyntaxHighlighterColors.DOC_COMMENT); + ourMap1.put(type, JavaHighlightingColors.DOC_COMMENT); } - ourMap1.put(XmlTokenType.XML_DATA_CHARACTERS, SyntaxHighlighterColors.DOC_COMMENT); - ourMap1.put(XmlTokenType.XML_REAL_WHITE_SPACE, SyntaxHighlighterColors.DOC_COMMENT); - ourMap1.put(XmlTokenType.TAG_WHITE_SPACE, SyntaxHighlighterColors.DOC_COMMENT); + ourMap1.put(XmlTokenType.XML_DATA_CHARACTERS, JavaHighlightingColors.DOC_COMMENT); + ourMap1.put(XmlTokenType.XML_REAL_WHITE_SPACE, JavaHighlightingColors.DOC_COMMENT); + ourMap1.put(XmlTokenType.TAG_WHITE_SPACE, JavaHighlightingColors.DOC_COMMENT); - ourMap1.put(JavaTokenType.INTEGER_LITERAL, SyntaxHighlighterColors.NUMBER); - ourMap1.put(JavaTokenType.LONG_LITERAL, SyntaxHighlighterColors.NUMBER); - ourMap1.put(JavaTokenType.FLOAT_LITERAL, SyntaxHighlighterColors.NUMBER); - ourMap1.put(JavaTokenType.DOUBLE_LITERAL, SyntaxHighlighterColors.NUMBER); - ourMap1.put(JavaTokenType.STRING_LITERAL, SyntaxHighlighterColors.STRING); - ourMap1.put(StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN, SyntaxHighlighterColors.VALID_STRING_ESCAPE); - ourMap1.put(StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN, SyntaxHighlighterColors.INVALID_STRING_ESCAPE); - ourMap1.put(StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN, SyntaxHighlighterColors.INVALID_STRING_ESCAPE); - ourMap1.put(JavaTokenType.CHARACTER_LITERAL, SyntaxHighlighterColors.STRING); + ourMap1.put(JavaTokenType.INTEGER_LITERAL, JavaHighlightingColors.NUMBER); + ourMap1.put(JavaTokenType.LONG_LITERAL, JavaHighlightingColors.NUMBER); + ourMap1.put(JavaTokenType.FLOAT_LITERAL, JavaHighlightingColors.NUMBER); + ourMap1.put(JavaTokenType.DOUBLE_LITERAL, JavaHighlightingColors.NUMBER); + ourMap1.put(JavaTokenType.STRING_LITERAL, JavaHighlightingColors.STRING); + ourMap1.put(StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN, JavaHighlightingColors.VALID_STRING_ESCAPE); + ourMap1.put(StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN, JavaHighlightingColors.INVALID_STRING_ESCAPE); + ourMap1.put(StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN, JavaHighlightingColors.INVALID_STRING_ESCAPE); + ourMap1.put(JavaTokenType.CHARACTER_LITERAL, JavaHighlightingColors.STRING); - ourMap1.put(JavaTokenType.LPARENTH, SyntaxHighlighterColors.PARENTHS); - ourMap1.put(JavaTokenType.RPARENTH, SyntaxHighlighterColors.PARENTHS); + ourMap1.put(JavaTokenType.LPARENTH, JavaHighlightingColors.PARENTHS); + ourMap1.put(JavaTokenType.RPARENTH, JavaHighlightingColors.PARENTHS); - ourMap1.put(JavaTokenType.LBRACE, SyntaxHighlighterColors.BRACES); - ourMap1.put(JavaTokenType.RBRACE, SyntaxHighlighterColors.BRACES); + ourMap1.put(JavaTokenType.LBRACE, JavaHighlightingColors.BRACES); + ourMap1.put(JavaTokenType.RBRACE, JavaHighlightingColors.BRACES); - ourMap1.put(JavaTokenType.LBRACKET, SyntaxHighlighterColors.BRACKETS); - ourMap1.put(JavaTokenType.RBRACKET, SyntaxHighlighterColors.BRACKETS); + ourMap1.put(JavaTokenType.LBRACKET, JavaHighlightingColors.BRACKETS); + ourMap1.put(JavaTokenType.RBRACKET, JavaHighlightingColors.BRACKETS); - ourMap1.put(JavaTokenType.COMMA, SyntaxHighlighterColors.COMMA); - ourMap1.put(JavaTokenType.DOT, SyntaxHighlighterColors.DOT); - ourMap1.put(JavaTokenType.SEMICOLON, SyntaxHighlighterColors.JAVA_SEMICOLON); + ourMap1.put(JavaTokenType.COMMA, JavaHighlightingColors.COMMA); + ourMap1.put(JavaTokenType.DOT, JavaHighlightingColors.DOT); + ourMap1.put(JavaTokenType.SEMICOLON, JavaHighlightingColors.JAVA_SEMICOLON); - ourMap1.put(JavaTokenType.C_STYLE_COMMENT, SyntaxHighlighterColors.JAVA_BLOCK_COMMENT); - ourMap1.put(JavaDocElementType.DOC_COMMENT, SyntaxHighlighterColors.DOC_COMMENT); - ourMap1.put(JavaTokenType.END_OF_LINE_COMMENT, SyntaxHighlighterColors.LINE_COMMENT); + ourMap1.put(JavaTokenType.C_STYLE_COMMENT, JavaHighlightingColors.JAVA_BLOCK_COMMENT); + ourMap1.put(JavaDocElementType.DOC_COMMENT, JavaHighlightingColors.DOC_COMMENT); + ourMap1.put(JavaTokenType.END_OF_LINE_COMMENT, JavaHighlightingColors.LINE_COMMENT); ourMap1.put(TokenType.BAD_CHARACTER, HighlighterColors.BAD_CHARACTER); - ourMap1.put(JavaDocTokenType.DOC_TAG_NAME, SyntaxHighlighterColors.DOC_COMMENT); - ourMap2.put(JavaDocTokenType.DOC_TAG_NAME, SyntaxHighlighterColors.DOC_COMMENT_TAG); + ourMap1.put(JavaDocTokenType.DOC_TAG_NAME, JavaHighlightingColors.DOC_COMMENT); + ourMap2.put(JavaDocTokenType.DOC_TAG_NAME, JavaHighlightingColors.DOC_COMMENT_TAG); IElementType[] javaDocMarkup = new IElementType[]{XmlTokenType.XML_START_TAG_START, XmlTokenType.XML_END_TAG_START, @@ -110,8 +110,8 @@ public class JavaFileHighlighter extends SyntaxHighlighterBase { XmlTokenType.XML_EQ}; for (IElementType idx : javaDocMarkup) { - ourMap1.put(idx, SyntaxHighlighterColors.DOC_COMMENT); - ourMap2.put(idx, SyntaxHighlighterColors.DOC_COMMENT_MARKUP); + ourMap1.put(idx, JavaHighlightingColors.DOC_COMMENT); + ourMap2.put(idx, JavaHighlightingColors.DOC_COMMENT_MARKUP); } } diff --git a/java/java-impl/src/com/intellij/ide/highlighter/JavaHighlightingColors.java b/java/java-impl/src/com/intellij/ide/highlighter/JavaHighlightingColors.java new file mode 100644 index 000000000000..9d169ed7c0ad --- /dev/null +++ b/java/java-impl/src/com/intellij/ide/highlighter/JavaHighlightingColors.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2013 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.ide.highlighter; + +import com.intellij.openapi.editor.SyntaxHighlighterColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; + +/** + * Highlighting text attributes for Java language. + * + * @author Rustam Vishnyakov + */ +@SuppressWarnings("deprecation") // Later SyntaxHighlighterColors will be moved here. +public class JavaHighlightingColors { + public static final TextAttributesKey LINE_COMMENT = SyntaxHighlighterColors.LINE_COMMENT; + public static final TextAttributesKey JAVA_BLOCK_COMMENT = SyntaxHighlighterColors.JAVA_BLOCK_COMMENT; + public static final TextAttributesKey DOC_COMMENT = SyntaxHighlighterColors.DOC_COMMENT; + public static final TextAttributesKey KEYWORD = SyntaxHighlighterColors.KEYWORD; + public static final TextAttributesKey NUMBER = SyntaxHighlighterColors.NUMBER; + public static final TextAttributesKey STRING = SyntaxHighlighterColors.STRING; + public static final TextAttributesKey OPERATION_SIGN = SyntaxHighlighterColors.OPERATION_SIGN; + public static final TextAttributesKey PARENTHS = SyntaxHighlighterColors.PARENTHS; + public static final TextAttributesKey BRACKETS = SyntaxHighlighterColors.BRACKETS; + public static final TextAttributesKey BRACES = SyntaxHighlighterColors.BRACES; + public static final TextAttributesKey COMMA = SyntaxHighlighterColors.COMMA; + public static final TextAttributesKey DOT = SyntaxHighlighterColors.DOT; + public static final TextAttributesKey JAVA_SEMICOLON = SyntaxHighlighterColors.JAVA_SEMICOLON; + public static final TextAttributesKey DOC_COMMENT_TAG = SyntaxHighlighterColors.DOC_COMMENT_TAG; + public static final TextAttributesKey DOC_COMMENT_MARKUP = SyntaxHighlighterColors.DOC_COMMENT_MARKUP; + public static final TextAttributesKey VALID_STRING_ESCAPE = SyntaxHighlighterColors.VALID_STRING_ESCAPE; + public static final TextAttributesKey INVALID_STRING_ESCAPE = SyntaxHighlighterColors.INVALID_STRING_ESCAPE; +} diff --git a/java/java-impl/src/com/intellij/internal/BuildIcons.java b/java/java-impl/src/com/intellij/internal/BuildIcons.java index 5eaeacab738d..13eacd15bc03 100644 --- a/java/java-impl/src/com/intellij/internal/BuildIcons.java +++ b/java/java-impl/src/com/intellij/internal/BuildIcons.java @@ -21,15 +21,14 @@ package com.intellij.internal; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.FileUtilRt; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import java.awt.*; import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; +import java.util.*; public class BuildIcons { public static void main(String[] args) throws Exception { @@ -66,6 +65,9 @@ public class BuildIcons { System.out.println("Total icons: " + total); } + private static final Set<String> IMAGE_EXTENSIONS = ContainerUtil.newTroveSet(FileUtil.PATH_HASHING_STRATEGY, + "png", "gif", "jpg", "jpeg"); + private static void walk(File root, MultiMap<Pair<Integer,Integer>, String> dimToPath, File file) throws IOException { if (file.isDirectory()) { for (File child : file.listFiles()) { @@ -73,8 +75,7 @@ public class BuildIcons { } } else { - String extension = FileUtil.getExtension(file.getName()); - if ("png".equals(extension) || "gif".equals(extension) || "jpg".equals(extension) || "jpeg".equals(extension)) { + if (IMAGE_EXTENSIONS.contains(FileUtilRt.getExtension(file.getName()))) { String relativePath = file.getAbsolutePath().substring(root.getAbsolutePath().length() + 1); Image image = loadImage(file); File target; diff --git a/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java b/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java index edeed5c1032b..59449defd59a 100644 --- a/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java +++ b/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java @@ -42,6 +42,7 @@ import com.intellij.openapi.projectRoots.ex.PathUtilEx; import com.intellij.openapi.roots.*; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.jsp.JspFile; @@ -271,8 +272,9 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl for (String aPackage : packages) { writer.println(aPackage); } + //http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#runningjavadoc for (String source : sources) { - writer.println(source); + writer.println(StringUtil.wrapWithDoubleQuote(source)); } writer.println("-sourcepath"); OrderEnumerator enumerator = OrderEnumerator.orderEntries(myProject); @@ -294,7 +296,7 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl } sourcePath.append(file.getPath()); } - writer.println(sourcePath.toString()); + writer.println(StringUtil.wrapWithDoubleQuote(sourcePath.toString())); } finally { writer.close(); diff --git a/java/java-impl/src/com/intellij/openapi/module/BasePackageParameterFactory.java b/java/java-impl/src/com/intellij/openapi/module/BasePackageParameterFactory.java new file mode 100644 index 000000000000..e2f3308f7ef2 --- /dev/null +++ b/java/java-impl/src/com/intellij/openapi/module/BasePackageParameterFactory.java @@ -0,0 +1,106 @@ +/* + * Copyright 2000-2013 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.module; + +import com.intellij.ide.util.projectWizard.ProjectTemplateParameterFactory; +import com.intellij.ide.util.projectWizard.WizardInputField; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.impl.PsiNameHelperImpl; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.containers.ContainerUtil; + +import javax.swing.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Dmitry Avdeev + * Date: 2/1/13 + */ +public class BasePackageParameterFactory extends ProjectTemplateParameterFactory { + + private static final Condition<PsiPackage> PACKAGE_CONDITION = new Condition<PsiPackage>() { + @Override + public boolean value(PsiPackage aPackage) { + return JavaPsiFacade.getInstance(aPackage.getProject()).getNameHelper().isQualifiedName(aPackage.getQualifiedName()) && + Character.isLowerCase(aPackage.getName().charAt(0)); + } + }; + + @Override + public String getParameterId() { + return IJ_BASE_PACKAGE; + } + + @Override + public WizardInputField createField(final String defaultValue) { + + return new WizardInputField<JTextField>(IJ_BASE_PACKAGE, defaultValue) { + + private final JTextField myField = new JTextField(defaultValue); + + @Override + public String getLabel() { + return "Base package:"; + } + + @Override + public JTextField getComponent() { + return myField; + } + + @Override + public String getValue() { + return myField.getText(); + } + + @Override + public Map<String, String> getValues() { + HashMap<String, String> map = new HashMap<String, String>(2); + map.put(getId(), getValue()); + map.put("IJ_BASE_PACKAGE_DIR", getValue().replace('.', '/')); + return map; + } + + @Override + public boolean validate() throws ConfigurationException { + if (!PsiNameHelperImpl.getInstance().isQualifiedName(getValue())) { + throw new ConfigurationException(getValue() + " is not a valid package name"); + } + return true; + } + }; + } + + @Override + public String detectParameterValue(Project project) { + PsiPackage root = JavaPsiFacade.getInstance(project).findPackage(""); + if (root == null) return null; + String name = getBasePackage(root, GlobalSearchScope.projectScope(project)).getQualifiedName(); + return StringUtil.isEmpty(name) ? null : name; + } + + private static PsiPackage getBasePackage(PsiPackage pack, GlobalSearchScope scope) { + List<PsiPackage> subPackages = ContainerUtil.filter(pack.getSubPackages(scope), PACKAGE_CONDITION); + return subPackages.size() == 1 ? getBasePackage(subPackages.get(0), scope) : pack; + } +} diff --git a/java/java-impl/src/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java b/java/java-impl/src/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java index 96956e40e65d..3c584077122e 100644 --- a/java/java-impl/src/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java +++ b/java/java-impl/src/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java @@ -17,6 +17,7 @@ package com.intellij.openapi.options.colors.pages; import com.intellij.application.options.colors.InspectionColorSettingsPage; import com.intellij.ide.highlighter.JavaFileHighlighter; +import com.intellij.ide.highlighter.JavaHighlightingColors; import com.intellij.openapi.editor.HighlighterColors; import com.intellij.openapi.editor.SyntaxHighlighterColors; import com.intellij.openapi.editor.colors.CodeInsightColors; @@ -39,27 +40,27 @@ import java.util.Map; public class JavaColorSettingsPage implements ColorSettingsPage, InspectionColorSettingsPage, DisplayPrioritySortable { private static final AttributesDescriptor[] ourDescriptors = { - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.keyword"), SyntaxHighlighterColors.KEYWORD), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.number"), SyntaxHighlighterColors.NUMBER), - - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.string"), SyntaxHighlighterColors.STRING), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.valid.escape.in.string"), SyntaxHighlighterColors.VALID_STRING_ESCAPE), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.invalid.escape.in.string"), SyntaxHighlighterColors.INVALID_STRING_ESCAPE), - - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.operator.sign"), SyntaxHighlighterColors.OPERATION_SIGN), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.parentheses"), SyntaxHighlighterColors.PARENTHS), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.braces"), SyntaxHighlighterColors.BRACES), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.brackets"), SyntaxHighlighterColors.BRACKETS), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.comma"), SyntaxHighlighterColors.COMMA), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.semicolon"), SyntaxHighlighterColors.JAVA_SEMICOLON), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.dot"), SyntaxHighlighterColors.DOT), - - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.line.comment"), SyntaxHighlighterColors.LINE_COMMENT), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.block.comment"), SyntaxHighlighterColors.JAVA_BLOCK_COMMENT), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.javadoc.comment"), SyntaxHighlighterColors.DOC_COMMENT), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.javadoc.tag"), SyntaxHighlighterColors.DOC_COMMENT_TAG), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.keyword"), JavaHighlightingColors.KEYWORD), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.number"), JavaHighlightingColors.NUMBER), + + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.string"), JavaHighlightingColors.STRING), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.valid.escape.in.string"), JavaHighlightingColors.VALID_STRING_ESCAPE), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.invalid.escape.in.string"), JavaHighlightingColors.INVALID_STRING_ESCAPE), + + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.operator.sign"), JavaHighlightingColors.OPERATION_SIGN), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.parentheses"), JavaHighlightingColors.PARENTHS), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.braces"), JavaHighlightingColors.BRACES), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.brackets"), JavaHighlightingColors.BRACKETS), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.comma"), JavaHighlightingColors.COMMA), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.semicolon"), JavaHighlightingColors.JAVA_SEMICOLON), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.dot"), JavaHighlightingColors.DOT), + + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.line.comment"), JavaHighlightingColors.LINE_COMMENT), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.block.comment"), JavaHighlightingColors.JAVA_BLOCK_COMMENT), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.javadoc.comment"), JavaHighlightingColors.DOC_COMMENT), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.javadoc.tag"), JavaHighlightingColors.DOC_COMMENT_TAG), new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.javadoc.tag.value"), CodeInsightColors.DOC_COMMENT_TAG_VALUE), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.javadoc.markup"), SyntaxHighlighterColors.DOC_COMMENT_MARKUP), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.javadoc.markup"), JavaHighlightingColors.DOC_COMMENT_MARKUP), new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.class"), CodeInsightColors.CLASS_NAME_ATTRIBUTES), new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.anonymous.class"), CodeInsightColors.ANONYMOUS_CLASS_NAME_ATTRIBUTES), @@ -83,8 +84,6 @@ public class JavaColorSettingsPage implements ColorSettingsPage, InspectionColor new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.abstract.method"), CodeInsightColors.ABSTRACT_METHOD_ATTRIBUTES), new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.inherited.method"), CodeInsightColors.INHERITED_METHOD_ATTRIBUTES), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.bad.character"), HighlighterColors.BAD_CHARACTER), - new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.annotation.name"), CodeInsightColors.ANNOTATION_NAME_ATTRIBUTES), new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.annotation.attribute.name"), CodeInsightColors.ANNOTATION_ATTRIBUTE_NAME_ATTRIBUTES) }; @@ -159,7 +158,6 @@ public class JavaColorSettingsPage implements ColorSettingsPage, InspectionColor return "/* Block comment */\n" + "import <class>java.util.Date</class>;\n" + - " Bad characters: \\n #\n" + "/**\n" + " * Doc comment here for <code>SomeClass</code>\n" + " * @see <class>Math</class>#<methodCall>sin</methodCall>(double)\n" + diff --git a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java index 519b39e0e34c..ae5381090152 100644 --- a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java +++ b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaSdkImpl.java @@ -294,6 +294,13 @@ public class JavaSdkImpl extends JavaSdk { if (appleDocs != null) { sdkModificator.addRoot(appleDocs, JavadocOrderRootType.getInstance()); } + + if (commonDocs == null && appleDocs == null && sources == null) { + String url = getDefaultDocumentationUrl(sdk); + if (url != null) { + sdkModificator.addRoot(VirtualFileManager.getInstance().findFileByUrl(url), JavadocOrderRootType.getInstance()); + } + } } attachJdkAnnotations(sdkModificator); sdkModificator.commitChanges(); diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java index fd928aaf5547..9cfcdfd16778 100644 --- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java +++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.codeStyle.arrangement; +import com.intellij.ide.highlighter.JavaHighlightingColors; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.SyntaxHighlighterColors; @@ -400,7 +401,7 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>, return attributes; } if (type == ArrangementSettingType.MODIFIER) { - return getAttributes(scheme, SyntaxHighlighterColors.KEYWORD); + return getAttributes(scheme, JavaHighlightingColors.KEYWORD); } else if (type == ArrangementSettingType.TYPE) { return getAttributes(scheme, CodeInsightColors.CLASS_NAME_ATTRIBUTES, CodeInsightColors.INTERFACE_NAME_ATTRIBUTES); diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java index e7c9b3e162b5..f6150031f602 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java @@ -242,7 +242,15 @@ public class ReferenceAdjuster { private static void dequalifyImpl(@NotNull CompositeElement reference) { final ASTNode qualifier = reference.findChildByRole(ChildRole.QUALIFIER); if (qualifier != null) { + ASTNode firstChildNode = qualifier.getFirstChildNode(); + boolean markToReformatBefore = firstChildNode instanceof TreeElement && CodeEditUtil.isMarkedToReformatBefore((TreeElement)firstChildNode); reference.deleteChildInternal(qualifier); + if (markToReformatBefore) { + firstChildNode = reference.getFirstChildNode(); + if (firstChildNode != null) { + CodeEditUtil.markToReformatBefore(firstChildNode, true); + } + } } } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FilePathReferenceProvider.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FilePathReferenceProvider.java index 7338c9798308..d14698237643 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FilePathReferenceProvider.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FilePathReferenceProvider.java @@ -23,7 +23,10 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.util.ProcessingContext; +import com.intellij.util.containers.*; +import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -44,7 +47,18 @@ public class FilePathReferenceProvider extends PsiReferenceProvider { @NotNull public PsiReference[] getReferencesByElement(PsiElement element, String text, int offset, final boolean soft) { + return getReferencesByElement(element, text, offset, soft, Module.EMPTY_ARRAY); + } + + @NotNull + public PsiReference[] getReferencesByElement(PsiElement element, + String text, + int offset, + final boolean soft, + final @NotNull Module... forModules) { return new FileReferenceSet(text, element, offset, this, true, myEndingSlashNotAllowed) { + + @Override protected boolean isSoft() { return soft; @@ -67,9 +81,17 @@ public class FilePathReferenceProvider extends PsiReferenceProvider { } @Override - @NotNull public Collection<PsiFileSystemItem> computeDefaultContexts() { - final Module module = ModuleUtil.findModuleForPsiElement(getElement()); - return getRoots(module, true); + @NotNull + public Collection<PsiFileSystemItem> computeDefaultContexts() { + Set<PsiFileSystemItem> systemItems = new HashSet<PsiFileSystemItem>(); + if (forModules.length > 0) { + for (Module forModule : forModules) { + systemItems.addAll(getRoots(forModule, true)); + } + } else { + systemItems.addAll(getRoots(ModuleUtil.findModuleForPsiElement(getElement()), true)); + } + return systemItems; } @Override @@ -87,7 +109,6 @@ public class FilePathReferenceProvider extends PsiReferenceProvider { }; } }.getAllReferences(); - } @Override @@ -154,5 +175,4 @@ public class FilePathReferenceProvider extends PsiReferenceProvider { } return result; } - } diff --git a/java/java-impl/src/com/intellij/psi/util/proximity/KnownElementWeigher.java b/java/java-impl/src/com/intellij/psi/util/proximity/KnownElementWeigher.java index 73e8f14b5f50..4f492e818a20 100644 --- a/java/java-impl/src/com/intellij/psi/util/proximity/KnownElementWeigher.java +++ b/java/java-impl/src/com/intellij/psi/util/proximity/KnownElementWeigher.java @@ -48,12 +48,14 @@ public class KnownElementWeigher extends ProximityWeigher { final PsiMethod method = (PsiMethod)element; final PsiClass containingClass = method.getContainingClass(); if (containingClass != null) { - if ("finalize".equals(method.getName()) || "registerNatives".equals(method.getName())) { + String methodName = method.getName(); + if ("finalize".equals(methodName) || "registerNatives".equals(methodName) || "getClass".equals(methodName) || + methodName.startsWith("wait") || methodName.startsWith("notify")) { if (CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())) { return -1; } } - if ("subSequence".equals(method.getName())) { + if ("subSequence".equals(methodName)) { if (CommonClassNames.JAVA_LANG_STRING.equals(containingClass.getQualifiedName())) { return -1; } diff --git a/java/java-impl/src/com/intellij/refactoring/actions/AnonymousToInnerAction.java b/java/java-impl/src/com/intellij/refactoring/actions/AnonymousToInnerAction.java index ef797c391279..9e8ab42443be 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/AnonymousToInnerAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/AnonymousToInnerAction.java @@ -24,17 +24,18 @@ import com.intellij.psi.PsiNewExpression; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.anonymousToInner.AnonymousToInnerHandler; +import org.jetbrains.annotations.NotNull; public class AnonymousToInnerAction extends BaseRefactoringAction { public boolean isAvailableInEditorOnly() { return true; } - public boolean isEnabledOnElements(PsiElement[] elements) { + public boolean isEnabledOnElements(@NotNull PsiElement[] elements) { return false; } - protected boolean isAvailableOnElementInEditorAndFile(final PsiElement element, final Editor editor, PsiFile file, DataContext context) { + protected boolean isAvailableOnElementInEditorAndFile(@NotNull final PsiElement element, @NotNull final Editor editor, @NotNull PsiFile file, @NotNull DataContext context) { final PsiElement targetElement = file.findElementAt(editor.getCaretModel().getOffset()); if (PsiTreeUtil.getParentOfType(targetElement, PsiAnonymousClass.class) != null) { return true; @@ -46,7 +47,7 @@ public class AnonymousToInnerAction extends BaseRefactoringAction { return newExpression != null && newExpression.getAnonymousClass() != null; } - public RefactoringActionHandler getHandler(DataContext dataContext) { + public RefactoringActionHandler getHandler(@NotNull DataContext dataContext) { return new AnonymousToInnerHandler(); } } diff --git a/java/java-impl/src/com/intellij/refactoring/actions/ConvertToInstanceMethodAction.java b/java/java-impl/src/com/intellij/refactoring/actions/ConvertToInstanceMethodAction.java index d0f11ebc6a75..6983e34f4020 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/ConvertToInstanceMethodAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/ConvertToInstanceMethodAction.java @@ -20,6 +20,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.psi.*; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.convertToInstanceMethod.ConvertToInstanceMethodHandler; +import org.jetbrains.annotations.NotNull; /** * @author dsl @@ -29,16 +30,16 @@ public class ConvertToInstanceMethodAction extends BaseRefactoringAction { return false; } - protected boolean isEnabledOnElements(PsiElement[] elements) { + protected boolean isEnabledOnElements(@NotNull PsiElement[] elements) { return elements.length == 1 && elements[0] instanceof PsiMethod; } - protected boolean isAvailableOnElementInEditorAndFile(PsiElement element, final Editor editor, PsiFile file, DataContext context) { + protected boolean isAvailableOnElementInEditorAndFile(@NotNull PsiElement element, @NotNull final Editor editor, @NotNull PsiFile file, @NotNull DataContext context) { if (element instanceof PsiIdentifier) element = element.getParent(); return element instanceof PsiMethod && ((PsiMethod) element).hasModifierProperty(PsiModifier.STATIC); } - protected RefactoringActionHandler getHandler(DataContext dataContext) { + protected RefactoringActionHandler getHandler(@NotNull DataContext dataContext) { return new ConvertToInstanceMethodHandler(); } } diff --git a/java/java-impl/src/com/intellij/refactoring/actions/EncapsulateFieldsAction.java b/java/java-impl/src/com/intellij/refactoring/actions/EncapsulateFieldsAction.java index bfdc4db4b429..fc1762e85d9e 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/EncapsulateFieldsAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/EncapsulateFieldsAction.java @@ -25,6 +25,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.encapsulateFields.EncapsulateFieldsHandler; +import org.jetbrains.annotations.NotNull; public class EncapsulateFieldsAction extends BaseRefactoringAction { public boolean isAvailableInEditorOnly() { @@ -32,7 +33,7 @@ public class EncapsulateFieldsAction extends BaseRefactoringAction { } @Override - protected boolean isAvailableOnElementInEditorAndFile(PsiElement element, Editor editor, PsiFile file, DataContext context) { + protected boolean isAvailableOnElementInEditorAndFile(@NotNull PsiElement element, @NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext context) { final PsiElement psiElement = file.findElementAt(editor.getCaretModel().getOffset()); final PsiClass containingClass = PsiTreeUtil.getParentOfType(psiElement, PsiClass.class, false); if (containingClass != null) { @@ -44,7 +45,7 @@ public class EncapsulateFieldsAction extends BaseRefactoringAction { return false; } - public boolean isEnabledOnElements(PsiElement[] elements) { + public boolean isEnabledOnElements(@NotNull PsiElement[] elements) { if (elements.length == 1) { return elements[0] instanceof PsiClass && elements[0].getLanguage().isKindOf(JavaLanguage.INSTANCE) || isAcceptedField(elements[0]); } @@ -59,7 +60,7 @@ public class EncapsulateFieldsAction extends BaseRefactoringAction { return false; } - public RefactoringActionHandler getHandler(DataContext dataContext) { + public RefactoringActionHandler getHandler(@NotNull DataContext dataContext) { return new EncapsulateFieldsHandler(); } diff --git a/java/java-impl/src/com/intellij/refactoring/actions/InheritanceToDelegationAction.java b/java/java-impl/src/com/intellij/refactoring/actions/InheritanceToDelegationAction.java index 290cafd1911c..d97a86b80148 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/InheritanceToDelegationAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/InheritanceToDelegationAction.java @@ -21,20 +21,21 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.inheritanceToDelegation.InheritanceToDelegationHandler; +import org.jetbrains.annotations.NotNull; public class InheritanceToDelegationAction extends BaseRefactoringAction { public boolean isAvailableInEditorOnly() { return false; } - public boolean isEnabledOnElements(PsiElement[] elements) { + public boolean isEnabledOnElements(@NotNull PsiElement[] elements) { return elements.length == 1 && elements[0] instanceof PsiClass && !((PsiClass)elements[0]).isInterface() && elements[0].getLanguage().isKindOf(JavaLanguage.INSTANCE); } - public RefactoringActionHandler getHandler(DataContext dataContext) { + public RefactoringActionHandler getHandler(@NotNull DataContext dataContext) { return new InheritanceToDelegationHandler(); } }
\ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/actions/IntroduceParameterObjectAction.java b/java/java-impl/src/com/intellij/refactoring/actions/IntroduceParameterObjectAction.java index d2e348e0d8df..ec09e1c1fb34 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/IntroduceParameterObjectAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/IntroduceParameterObjectAction.java @@ -21,6 +21,7 @@ import com.intellij.psi.PsiMethod; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.introduceparameterobject.IntroduceParameterObjectHandler; +import org.jetbrains.annotations.NotNull; public class IntroduceParameterObjectAction extends BaseRefactoringAction { @@ -28,11 +29,11 @@ public class IntroduceParameterObjectAction extends BaseRefactoringAction { return false; } - protected boolean isEnabledOnElements(final PsiElement[] elements) { + protected boolean isEnabledOnElements(@NotNull final PsiElement[] elements) { return elements.length == 1 && PsiTreeUtil.getParentOfType(elements[0], PsiMethod.class, false) != null; } - protected RefactoringActionHandler getHandler(DataContext context) { + protected RefactoringActionHandler getHandler(@NotNull DataContext context) { return new IntroduceParameterObjectHandler(); } } diff --git a/java/java-impl/src/com/intellij/refactoring/actions/InvertBooleanAction.java b/java/java-impl/src/com/intellij/refactoring/actions/InvertBooleanAction.java index 7ad4645837d5..3f95b678cafc 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/InvertBooleanAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/InvertBooleanAction.java @@ -20,6 +20,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.psi.*; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.invertBoolean.InvertBooleanHandler; +import org.jetbrains.annotations.NotNull; /** * @author ven @@ -29,11 +30,11 @@ public class InvertBooleanAction extends BaseRefactoringAction { return false; } - protected boolean isEnabledOnElements(PsiElement[] elements) { + protected boolean isEnabledOnElements(@NotNull PsiElement[] elements) { return elements.length == 1 && (elements[0] instanceof PsiMethod || elements[0] instanceof PsiVariable); } - protected boolean isAvailableOnElementInEditorAndFile(final PsiElement element, final Editor editor, PsiFile file, DataContext context) { + protected boolean isAvailableOnElementInEditorAndFile(@NotNull final PsiElement element, @NotNull final Editor editor, @NotNull PsiFile file, @NotNull DataContext context) { if (element instanceof PsiVariable) { return PsiType.BOOLEAN.equals(((PsiVariable) element).getType()); } @@ -43,7 +44,7 @@ public class InvertBooleanAction extends BaseRefactoringAction { return false; } - protected RefactoringActionHandler getHandler(DataContext dataContext) { + protected RefactoringActionHandler getHandler(@NotNull DataContext dataContext) { return new InvertBooleanHandler(); } } diff --git a/java/java-impl/src/com/intellij/refactoring/actions/MakeStaticAction.java b/java/java-impl/src/com/intellij/refactoring/actions/MakeStaticAction.java index 4514b13c2eab..ec329966493f 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/MakeStaticAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/MakeStaticAction.java @@ -29,17 +29,18 @@ import com.intellij.openapi.editor.Editor; import com.intellij.psi.*; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.makeStatic.MakeStaticHandler; +import org.jetbrains.annotations.NotNull; public class MakeStaticAction extends BaseRefactoringAction { protected boolean isAvailableInEditorOnly() { return false; } - protected boolean isEnabledOnElements(PsiElement[] elements) { + protected boolean isEnabledOnElements(@NotNull PsiElement[] elements) { return (elements.length == 1) && (elements[0] instanceof PsiMethod) && !((PsiMethod)elements[0]).isConstructor(); } - protected boolean isAvailableOnElementInEditorAndFile(PsiElement element, final Editor editor, PsiFile file, DataContext context) { + protected boolean isAvailableOnElementInEditorAndFile(@NotNull PsiElement element, @NotNull final Editor editor, @NotNull PsiFile file, @NotNull DataContext context) { if (element instanceof PsiIdentifier) { element = element.getParent(); } @@ -47,7 +48,7 @@ public class MakeStaticAction extends BaseRefactoringAction { MakeStaticHandler.validateTarget((PsiTypeParameterListOwner) element) == null; } - protected RefactoringActionHandler getHandler(DataContext dataContext) { + protected RefactoringActionHandler getHandler(@NotNull DataContext dataContext) { return new MakeStaticHandler(); } } diff --git a/java/java-impl/src/com/intellij/refactoring/actions/MethodDuplicatesAction.java b/java/java-impl/src/com/intellij/refactoring/actions/MethodDuplicatesAction.java index 7982d07a616e..4abd04b6e166 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/MethodDuplicatesAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/MethodDuplicatesAction.java @@ -19,6 +19,7 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.psi.PsiElement; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.util.duplicates.MethodDuplicatesHandler; +import org.jetbrains.annotations.NotNull; /** * @author dsl @@ -28,11 +29,11 @@ public class MethodDuplicatesAction extends BaseRefactoringAction { return true; } - protected boolean isEnabledOnElements(PsiElement[] elements) { + protected boolean isEnabledOnElements(@NotNull PsiElement[] elements) { return false; } - protected RefactoringActionHandler getHandler(DataContext dataContext) { + protected RefactoringActionHandler getHandler(@NotNull DataContext dataContext) { return new MethodDuplicatesHandler(); } } diff --git a/java/java-impl/src/com/intellij/refactoring/actions/RemoveMiddlemanAction.java b/java/java-impl/src/com/intellij/refactoring/actions/RemoveMiddlemanAction.java index 77223a97b3d9..b7171948f1aa 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/RemoveMiddlemanAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/RemoveMiddlemanAction.java @@ -23,15 +23,16 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.removemiddleman.RemoveMiddlemanHandler; +import org.jetbrains.annotations.NotNull; public class RemoveMiddlemanAction extends BaseRefactoringAction{ - protected RefactoringActionHandler getHandler(DataContext context) { + protected RefactoringActionHandler getHandler(@NotNull DataContext context) { return new RemoveMiddlemanHandler(); } @Override - protected boolean isAvailableOnElementInEditorAndFile(PsiElement element, Editor editor, PsiFile file, DataContext context) { + protected boolean isAvailableOnElementInEditorAndFile(@NotNull PsiElement element, @NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext context) { return element instanceof PsiField; } @@ -39,7 +40,7 @@ public class RemoveMiddlemanAction extends BaseRefactoringAction{ return false; } - public boolean isEnabledOnElements(PsiElement[] elements) { + public boolean isEnabledOnElements(@NotNull PsiElement[] elements) { return elements.length == 1 && PsiTreeUtil.getParentOfType(elements[0], PsiField.class, false) != null; } } diff --git a/java/java-impl/src/com/intellij/refactoring/actions/ReplaceConstructorWithBuilderAction.java b/java/java-impl/src/com/intellij/refactoring/actions/ReplaceConstructorWithBuilderAction.java index 429aeed4e6c0..0775c65258a8 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/ReplaceConstructorWithBuilderAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/ReplaceConstructorWithBuilderAction.java @@ -27,6 +27,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.replaceConstructorWithBuilder.ReplaceConstructorWithBuilderHandler; +import org.jetbrains.annotations.NotNull; public class ReplaceConstructorWithBuilderAction extends BaseRefactoringAction{ protected boolean isAvailableInEditorOnly() { @@ -34,18 +35,18 @@ public class ReplaceConstructorWithBuilderAction extends BaseRefactoringAction{ } @Override - protected boolean isAvailableOnElementInEditorAndFile(PsiElement element, Editor editor, PsiFile file, DataContext context) { + protected boolean isAvailableOnElementInEditorAndFile(@NotNull PsiElement element, @NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext context) { final int offset = editor.getCaretModel().getOffset(); final PsiElement elementAt = file.findElementAt(offset); final PsiClass psiClass = ReplaceConstructorWithBuilderHandler.getParentNamedClass(elementAt); return psiClass != null && psiClass.getConstructors().length > 0; } - protected boolean isEnabledOnElements(final PsiElement[] elements) { + protected boolean isEnabledOnElements(@NotNull final PsiElement[] elements) { return false; } - protected RefactoringActionHandler getHandler(final DataContext dataContext) { + protected RefactoringActionHandler getHandler(@NotNull final DataContext dataContext) { return new ReplaceConstructorWithBuilderHandler(); } } diff --git a/java/java-impl/src/com/intellij/refactoring/actions/ReplaceConstructorWithFactoryAction.java b/java/java-impl/src/com/intellij/refactoring/actions/ReplaceConstructorWithFactoryAction.java index d73d802eb1aa..1d32d0ee5183 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/ReplaceConstructorWithFactoryAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/ReplaceConstructorWithFactoryAction.java @@ -22,6 +22,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.replaceConstructorWithFactory.ReplaceConstructorWithFactoryHandler; +import org.jetbrains.annotations.NotNull; /** * @author dsl @@ -31,13 +32,13 @@ public class ReplaceConstructorWithFactoryAction extends BaseRefactoringAction { return false; } - protected boolean isEnabledOnElements(PsiElement[] elements) { + protected boolean isEnabledOnElements(@NotNull PsiElement[] elements) { return elements.length == 1 && (elements[0] instanceof PsiMethod && ((PsiMethod)elements[0]).isConstructor() || elements[0] instanceof PsiClass) && elements[0].getLanguage().isKindOf(JavaLanguage.INSTANCE); } - protected RefactoringActionHandler getHandler(DataContext dataContext) { + protected RefactoringActionHandler getHandler(@NotNull DataContext dataContext) { return new ReplaceConstructorWithFactoryHandler(); } } diff --git a/java/java-impl/src/com/intellij/refactoring/actions/ReplaceMethodWithMethodObjectAction.java b/java/java-impl/src/com/intellij/refactoring/actions/ReplaceMethodWithMethodObjectAction.java index ad4433b1af56..e103ab110d36 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/ReplaceMethodWithMethodObjectAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/ReplaceMethodWithMethodObjectAction.java @@ -24,17 +24,18 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.psi.PsiElement; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.extractMethodObject.ExtractMethodObjectHandler; +import org.jetbrains.annotations.NotNull; public class ReplaceMethodWithMethodObjectAction extends BaseRefactoringAction{ protected boolean isAvailableInEditorOnly() { return true; } - protected boolean isEnabledOnElements(final PsiElement[] elements) { + protected boolean isEnabledOnElements(@NotNull final PsiElement[] elements) { return false; } - protected RefactoringActionHandler getHandler(final DataContext dataContext) { + protected RefactoringActionHandler getHandler(@NotNull final DataContext dataContext) { return new ExtractMethodObjectHandler(); } }
\ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/actions/TempWithQueryAction.java b/java/java-impl/src/com/intellij/refactoring/actions/TempWithQueryAction.java index 6717bc14dd56..704f6efa6dd5 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/TempWithQueryAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/TempWithQueryAction.java @@ -23,21 +23,22 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiLocalVariable; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.tempWithQuery.TempWithQueryHandler; +import org.jetbrains.annotations.NotNull; public class TempWithQueryAction extends BaseRefactoringAction{ public boolean isAvailableInEditorOnly() { return true; } - public boolean isEnabledOnElements(PsiElement[] elements) { + public boolean isEnabledOnElements(@NotNull PsiElement[] elements) { return false; } - public RefactoringActionHandler getHandler(DataContext dataContext) { + public RefactoringActionHandler getHandler(@NotNull DataContext dataContext) { return new TempWithQueryHandler(); } - protected boolean isAvailableOnElementInEditorAndFile(final PsiElement element, final Editor editor, PsiFile file, DataContext context) { + protected boolean isAvailableOnElementInEditorAndFile(@NotNull final PsiElement element, @NotNull final Editor editor, @NotNull PsiFile file, @NotNull DataContext context) { return element instanceof PsiLocalVariable && ((PsiLocalVariable) element).getInitializer() != null; } }
\ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/actions/TurnRefsToSuperAction.java b/java/java-impl/src/com/intellij/refactoring/actions/TurnRefsToSuperAction.java index db8ca11a9bbd..b4895335c37d 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/TurnRefsToSuperAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/TurnRefsToSuperAction.java @@ -21,17 +21,18 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.turnRefsToSuper.TurnRefsToSuperHandler; +import org.jetbrains.annotations.NotNull; public class TurnRefsToSuperAction extends BaseRefactoringAction { public boolean isAvailableInEditorOnly() { return false; } - public boolean isEnabledOnElements(PsiElement[] elements) { + public boolean isEnabledOnElements(@NotNull PsiElement[] elements) { return elements.length == 1 && elements[0] instanceof PsiClass && elements[0].getLanguage() == JavaLanguage.INSTANCE; } - public RefactoringActionHandler getHandler(DataContext dataContext) { + public RefactoringActionHandler getHandler(@NotNull DataContext dataContext) { return new TurnRefsToSuperHandler(); } }
\ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/actions/TypeCookAction.java b/java/java-impl/src/com/intellij/refactoring/actions/TypeCookAction.java index 03f14276cc19..f05c7aafe0c2 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/TypeCookAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/TypeCookAction.java @@ -24,6 +24,7 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.typeCook.TypeCookHandler; +import org.jetbrains.annotations.NotNull; public class TypeCookAction extends BaseRefactoringAction { @@ -35,7 +36,7 @@ public class TypeCookAction extends BaseRefactoringAction { return language.equals(JavaLanguage.INSTANCE); } - public boolean isEnabledOnElements(PsiElement[] elements) { + public boolean isEnabledOnElements(@NotNull PsiElement[] elements) { Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext()); if (project == null) { @@ -59,7 +60,7 @@ public class TypeCookAction extends BaseRefactoringAction { return true; } - public RefactoringActionHandler getHandler(DataContext dataContext) { + public RefactoringActionHandler getHandler(@NotNull DataContext dataContext) { return getHandler(); } public RefactoringActionHandler getHandler() { diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java index 383ee32050f9..ea14d9734a99 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java @@ -71,7 +71,6 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Set; @@ -688,7 +687,7 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet for (final ParameterTableModelItemBase<ParameterInfoImpl> item : myParametersTableModel.getItems()) { if (item.parameter.oldParameterIndex < 0) { if (StringUtil.isEmpty(item.defaultValueCodeFragment.getText())) - return new ValidationInfo("Default value is missing. In the method call place new parameter value would be leaved blank"); + return new ValidationInfo("Default value is missing. In the method call, the new parameter value will be left blank"); } } } @@ -745,12 +744,8 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet } buffer.append(getMethodName()); buffer.append("("); - int paramIndent = buffer.toString().length(); - char[] chars = new char[paramIndent]; - Arrays.fill(chars, ' '); - - String indent = new String(chars); + String indent = StringUtil.repeatSymbol(' ', buffer.length()); List<ParameterTableModelItemBase<ParameterInfoImpl>> items = myParametersTableModel.getItems(); int curIndent = indent.length(); for (int i = 0; i < items.size(); i++) { @@ -775,9 +770,7 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet //buffer.append("\n"); buffer.append(" throws "); curIndent += 9; // ") throws ".length() - chars = new char[curIndent]; - Arrays.fill(chars, ' '); - indent = new String(chars); + indent = StringUtil.repeatSymbol(' ', curIndent); for (int i = 0; i < thrownExceptionsFragments.length; i++) { String text = thrownExceptionsFragments[i].getText(); if (i != 0) buffer.append(indent); diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java index 48887b6057a8..35e7ffafbfb9 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java @@ -21,6 +21,7 @@ import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.util.PsiFormatUtil; import com.intellij.psi.util.PsiUtil; @@ -47,7 +48,6 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.event.*; -import java.util.Arrays; /** @@ -448,13 +448,11 @@ public class ExtractMethodDialog extends AbstractExtractDialog { buffer.append(myNameField.getText()); } buffer.append("("); - int count = 0; - char[] chars = new char[buffer.toString().length()]; - Arrays.fill(chars, ' '); - final String INDENT = new String(chars); + final String INDENT = StringUtil.repeatSymbol(' ', buffer.length()); final ParameterTablePanel.VariableData[] datas = myInputVariables; + int count = 0; for (int i = 0; i < datas.length;i++) { ParameterTablePanel.VariableData data = datas[i]; if (data.passAsParameter) { diff --git a/java/java-impl/src/com/intellij/refactoring/listeners/impl/JavaRefactoringListenerManagerImpl.java b/java/java-impl/src/com/intellij/refactoring/listeners/impl/JavaRefactoringListenerManagerImpl.java index d0dd48aa7bf7..1f786d5c71b7 100644 --- a/java/java-impl/src/com/intellij/refactoring/listeners/impl/JavaRefactoringListenerManagerImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/listeners/impl/JavaRefactoringListenerManagerImpl.java @@ -27,7 +27,7 @@ import java.util.List; * @author yole */ public class JavaRefactoringListenerManagerImpl extends JavaRefactoringListenerManager { - private final List<MoveMemberListener> myMoveMemberListeners = ContainerUtil.createEmptyCOWList(); + private final List<MoveMemberListener> myMoveMemberListeners = ContainerUtil.createLockFreeCopyOnWriteList(); public void addMoveMembersListener(MoveMemberListener moveMembersListener) { myMoveMemberListeners.add(moveMembersListener); diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java index 68b873d95569..8e7fc3be5114 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java @@ -85,6 +85,7 @@ public class MoveClassesOrPackagesDialog extends RefactoringDialog { private JLabel myTargetDestinationLabel; private boolean myHavePackages; private boolean myTargetDirectoryFixed; + private boolean mySuggestToMoveToAnotherRoot; public MoveClassesOrPackagesDialog(Project project, boolean searchTextOccurences, @@ -228,10 +229,12 @@ public class MoveClassesOrPackagesDialog extends RefactoringDialog { String targetPackageName, final PsiDirectory initialTargetDirectory, boolean isTargetDirectoryFixed, + boolean suggestToMoveToAnotherRoot, boolean searchInComments, boolean searchForTextOccurences, String helpID) { myTargetDirectoryFixed = isTargetDirectoryFixed; + mySuggestToMoveToAnotherRoot = suggestToMoveToAnotherRoot; if (targetPackageName.length() != 0) { myWithBrowseButtonReference.prependItem(targetPackageName); myClassPackageChooser.prependItem(targetPackageName); @@ -471,7 +474,7 @@ public class MoveClassesOrPackagesDialog extends RefactoringDialog { if (ret != 0) return null; } - return ((DestinationFolderComboBox)myDestinationFolderCB).selectDirectory(targetPackage, true); + return ((DestinationFolderComboBox)myDestinationFolderCB).selectDirectory(targetPackage, mySuggestToMoveToAnotherRoot); } private VirtualFile[] getSourceRoots() { diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java index fda7483b4a21..cc1658f63a71 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesImpl.java @@ -78,7 +78,7 @@ public class MoveClassesOrPackagesImpl { new MoveClassesOrPackagesDialog(project, searchTextOccurences, psiElements, initialTargetElement, moveCallback); boolean searchInComments = JavaRefactoringSettings.getInstance().MOVE_SEARCH_IN_COMMENTS; boolean searchForTextOccurences = JavaRefactoringSettings.getInstance().MOVE_SEARCH_FOR_TEXT; - moveDialog.setData(psiElements, initialTargetPackageName, initialTargetDirectory, isTargetDirectoryFixed, searchInComments, + moveDialog.setData(psiElements, initialTargetPackageName, initialTargetDirectory, isTargetDirectoryFixed, initialTargetElement == null, searchInComments, searchForTextOccurences, HelpID.getMoveHelpID(psiElements[0])); moveDialog.show(); } diff --git a/java/java-impl/src/com/intellij/refactoring/rename/inplace/JavaResolveSnapshot.java b/java/java-impl/src/com/intellij/refactoring/rename/inplace/JavaResolveSnapshot.java index 2eb97dac7918..900cd9d5cb44 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/inplace/JavaResolveSnapshot.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/inplace/JavaResolveSnapshot.java @@ -43,8 +43,9 @@ class JavaResolveSnapshot extends ResolveSnapshotProvider.ResolveSnapshot { scope.accept(new JavaRecursiveElementWalkingVisitor() { @Override public void visitReferenceExpression(PsiReferenceExpression refExpr) { if (!refExpr.isQualified()) { - PsiElement resolved = refExpr.resolve(); - if (resolved instanceof PsiField) { + JavaResolveResult resolveResult = refExpr.advancedResolve(false); + final PsiElement resolved = resolveResult.getElement(); + if (resolved instanceof PsiField && resolveResult.isStaticsScopeCorrect()) { SmartPsiElementPointer key = pointerManager.createSmartPsiElementPointer(refExpr); SmartPsiElementPointer value = pointers.get(resolved); if (value == null) { diff --git a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java index 80563e9c28f7..01444d0cee4d 100644 --- a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryDialog.java @@ -107,7 +107,8 @@ public class ReplaceConstructorWithFactoryDialog extends RefactoringDialog { @NonNls final String[] nameSuggestions = new String[]{ "create" + myContainingClass.getName(), "new" + myContainingClass.getName(), - "getInstance" + "getInstance", + "newInstance" }; myNameField = new NameSuggestionsField(nameSuggestions, getProject()); myNameChangedListener = new NameSuggestionsField.DataChanged() { diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/actions/ChangeTypeSignatureAction.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/actions/ChangeTypeSignatureAction.java index d5dc2b00388c..b7eb338fe326 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeMigration/actions/ChangeTypeSignatureAction.java +++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/actions/ChangeTypeSignatureAction.java @@ -26,13 +26,14 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.actions.BaseRefactoringAction; import com.intellij.refactoring.typeMigration.ChangeTypeSignatureHandler; +import org.jetbrains.annotations.NotNull; public class ChangeTypeSignatureAction extends BaseRefactoringAction { public boolean isAvailableInEditorOnly() { return false; } - public boolean isEnabledOnElements(PsiElement[] elements) { + public boolean isEnabledOnElements(@NotNull PsiElement[] elements) { Project currProject = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext()); if (currProject == null) { @@ -50,7 +51,7 @@ public class ChangeTypeSignatureAction extends BaseRefactoringAction { return true; } - protected boolean isAvailableOnElementInEditorAndFile(final PsiElement element, final Editor editor, PsiFile file, DataContext context) { + protected boolean isAvailableOnElementInEditorAndFile(@NotNull final PsiElement element, @NotNull final Editor editor, @NotNull PsiFile file, @NotNull DataContext context) { final int offset = TargetElementUtilBase.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset()); final PsiElement psiElement = file.findElementAt(offset); final PsiReferenceParameterList referenceParameterList = PsiTreeUtil.getParentOfType(psiElement, PsiReferenceParameterList.class); @@ -60,7 +61,7 @@ public class ChangeTypeSignatureAction extends BaseRefactoringAction { return PsiTreeUtil.getParentOfType(psiElement, PsiTypeElement.class) != null; } - public RefactoringActionHandler getHandler(DataContext dataContext) { + public RefactoringActionHandler getHandler(@NotNull DataContext dataContext) { return new ChangeTypeSignatureHandler(); } } diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java b/java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java index 21fba5c6643d..a878763f9eb7 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java +++ b/java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java @@ -108,9 +108,10 @@ public final class Match { super.visitReferenceExpression(expression); final PsiElement resolved = expression.resolve(); if (resolved != null && Comparing.equal(resolved.getContainingFile(), getMatchEnd().getContainingFile())) { - final TextRange range = resolved.getTextRange(); - if (getMatchStart().getTextOffset() <= range.getStartOffset() && - range.getEndOffset() <= getMatchEnd().getTextRange().getEndOffset()) { + final TextRange range = checkRange(resolved); + final TextRange startRange = checkRange(getMatchStart()); + final TextRange endRange = checkRange(getMatchEnd()); + if (startRange.getStartOffset() <= range.getStartOffset() && range.getEndOffset() <= endRange.getEndOffset()) { valueDependsOnReplacedScope[0] = true; } } @@ -291,8 +292,10 @@ public final class Match { if (!outVariables.contains(variable)) { final PsiIdentifier identifier = variable.getNameIdentifier(); if (identifier != null) { - if (identifier.getTextRange().getStartOffset() >= getMatchStart().getTextRange().getStartOffset() && - identifier.getTextRange().getEndOffset() <= getMatchEnd().getTextRange().getEndOffset()) { + final TextRange textRange = checkRange(identifier); + final TextRange startRange = checkRange(getMatchStart()); + final TextRange endRange = checkRange(getMatchEnd()); + if (textRange.getStartOffset() >= startRange.getStartOffset() && textRange.getEndOffset() <= endRange.getEndOffset()) { final String name = variable.getName(); LOG.assertTrue(name != null); PsiDeclarationStatement statement = @@ -314,6 +317,12 @@ public final class Match { } } + private static TextRange checkRange(final PsiElement element) { + final TextRange endRange = element.getTextRange(); + LOG.assertTrue(endRange != null, element); + return endRange; + } + public PsiElement replaceWithExpression(final PsiExpression psiExpression) throws IncorrectOperationException { final PsiElement matchStart = getMatchStart(); LOG.assertTrue(matchStart == getMatchEnd()); @@ -324,8 +333,9 @@ public final class Match { } TextRange getTextRange() { - return new TextRange(getMatchStart().getTextRange().getStartOffset(), - getMatchEnd().getTextRange().getEndOffset()); + final TextRange startRange = checkRange(getMatchStart()); + final TextRange endRange = checkRange(getMatchEnd()); + return new TextRange(startRange.getStartOffset(), endRange.getEndOffset()); } @Nullable diff --git a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueAction.java b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueAction.java index ecc505629b44..026fa135fdb3 100644 --- a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueAction.java +++ b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueAction.java @@ -21,10 +21,11 @@ import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.actions.BaseRefactoringAction; +import org.jetbrains.annotations.NotNull; public class WrapReturnValueAction extends BaseRefactoringAction{ - protected RefactoringActionHandler getHandler(DataContext context){ + protected RefactoringActionHandler getHandler(@NotNull DataContext context){ return new WrapReturnValueHandler(); } @@ -33,7 +34,7 @@ public class WrapReturnValueAction extends BaseRefactoringAction{ } @Override - protected boolean isAvailableOnElementInEditorAndFile(PsiElement element, Editor editor, PsiFile file, DataContext context) { + protected boolean isAvailableOnElementInEditorAndFile(@NotNull PsiElement element, @NotNull Editor editor, @NotNull PsiFile file, @NotNull DataContext context) { final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.class, false); if (psiMethod != null && !(psiMethod instanceof PsiCompiledElement)) { final PsiType returnType = psiMethod.getReturnType(); @@ -42,7 +43,7 @@ public class WrapReturnValueAction extends BaseRefactoringAction{ return false; } - public boolean isEnabledOnElements(PsiElement[] elements) { + public boolean isEnabledOnElements(@NotNull PsiElement[] elements) { if (elements.length != 1) { return false; } diff --git a/java/java-impl/src/com/intellij/slicer/SliceBackwardAction.java b/java/java-impl/src/com/intellij/slicer/SliceBackwardAction.java index 30ff46b81ef0..0ad568907ee4 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceBackwardAction.java +++ b/java/java-impl/src/com/intellij/slicer/SliceBackwardAction.java @@ -17,6 +17,7 @@ package com.intellij.slicer; import com.intellij.codeInsight.CodeInsightActionHandler; import com.intellij.codeInsight.actions.CodeInsightAction; +import org.jetbrains.annotations.NotNull; /** * @author cdr @@ -24,6 +25,7 @@ import com.intellij.codeInsight.actions.CodeInsightAction; public class SliceBackwardAction extends CodeInsightAction{ private final SliceHandler myHandler = new SliceHandler(true); + @NotNull @Override protected CodeInsightActionHandler getHandler() { return myHandler; diff --git a/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java b/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java index f561ea84e970..688abc6d8d64 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java +++ b/java/java-impl/src/com/intellij/slicer/SliceForwardAction.java @@ -17,6 +17,7 @@ package com.intellij.slicer; import com.intellij.codeInsight.CodeInsightActionHandler; import com.intellij.codeInsight.actions.CodeInsightAction; +import org.jetbrains.annotations.NotNull; /** * @author cdr @@ -24,6 +25,7 @@ import com.intellij.codeInsight.actions.CodeInsightAction; public class SliceForwardAction extends CodeInsightAction{ private final SliceHandler myHandler = new SliceForwardHandler(); + @NotNull @Override protected CodeInsightActionHandler getHandler() { return myHandler; diff --git a/java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzer.java b/java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzer.java index 37780b1fc2c8..4216d0070bd9 100644 --- a/java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzer.java +++ b/java/java-impl/src/com/intellij/slicer/SliceNullnessAnalyzer.java @@ -18,6 +18,7 @@ package com.intellij.slicer; import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.codeInsight.PsiEquivalenceUtil; import com.intellij.codeInspection.dataFlow.DfaUtil; +import com.intellij.codeInspection.dataFlow.Nullness; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.ide.util.treeView.AbstractTreeStructure; import com.intellij.openapi.application.ApplicationManager; @@ -174,16 +175,16 @@ public class SliceNullnessAnalyzer { else { SliceUsage sliceUsage = element.getValue(); final PsiElement value = sliceUsage.getElement(); - DfaUtil.Nullness nullness = ApplicationManager.getApplication().runReadAction(new Computable<DfaUtil.Nullness>() { + Nullness nullness = ApplicationManager.getApplication().runReadAction(new Computable<Nullness>() { @Override - public DfaUtil.Nullness compute() { + public Nullness compute() { return checkNullness(value); } }); - if (nullness == DfaUtil.Nullness.NULL) { + if (nullness == Nullness.NULLABLE) { group(element, map, NullAnalysisResult.NULLS).add(value); } - else if (nullness == DfaUtil.Nullness.NOT_NULL) { + else if (nullness == Nullness.NOT_NULL) { group(element, map, NullAnalysisResult.NOT_NULLS).add(value); } else { @@ -210,26 +211,26 @@ public class SliceNullnessAnalyzer { } @NotNull - private static DfaUtil.Nullness checkNullness(final PsiElement element) { + private static Nullness checkNullness(final PsiElement element) { // null PsiElement value = element; if (value instanceof PsiExpression) { value = PsiUtil.deparenthesizeExpression((PsiExpression)value); } if (value instanceof PsiLiteralExpression) { - return ((PsiLiteralExpression)value).getValue() == null ? DfaUtil.Nullness.NULL : DfaUtil.Nullness.NOT_NULL; + return ((PsiLiteralExpression)value).getValue() == null ? Nullness.NULLABLE : Nullness.NOT_NULL; } // not null - if (value instanceof PsiNewExpression) return DfaUtil.Nullness.NOT_NULL; - if (value instanceof PsiThisExpression) return DfaUtil.Nullness.NOT_NULL; + if (value instanceof PsiNewExpression) return Nullness.NOT_NULL; + if (value instanceof PsiThisExpression) return Nullness.NOT_NULL; if (value instanceof PsiMethodCallExpression) { PsiMethod method = ((PsiMethodCallExpression)value).resolveMethod(); - if (method != null && NullableNotNullManager.isNotNull(method)) return DfaUtil.Nullness.NOT_NULL; - if (method != null && NullableNotNullManager.isNullable(method)) return DfaUtil.Nullness.NULL; + if (method != null && NullableNotNullManager.isNotNull(method)) return Nullness.NOT_NULL; + if (method != null && NullableNotNullManager.isNullable(method)) return Nullness.NULLABLE; } if (value instanceof PsiPolyadicExpression && ((PsiPolyadicExpression)value).getOperationTokenType() == JavaTokenType.PLUS) { - return DfaUtil.Nullness.NOT_NULL; // "xxx" + var + return Nullness.NOT_NULL; // "xxx" + var } // unfortunately have to resolve here, since there can be no subnodes @@ -243,23 +244,23 @@ public class SliceNullnessAnalyzer { } if (value instanceof PsiParameter && ((PsiParameter)value).getDeclarationScope() instanceof PsiCatchSection) { // exception thrown is always not null - return DfaUtil.Nullness.NOT_NULL; + return Nullness.NOT_NULL; } if (value instanceof PsiLocalVariable || value instanceof PsiParameter) { - DfaUtil.Nullness result = DfaUtil.checkNullness((PsiVariable)value, context); - if (result != DfaUtil.Nullness.UNKNOWN) { + Nullness result = DfaUtil.checkNullness((PsiVariable)value, context); + if (result != Nullness.UNKNOWN) { return result; } } if (value instanceof PsiModifierListOwner) { - if (NullableNotNullManager.isNotNull((PsiModifierListOwner)value)) return DfaUtil.Nullness.NOT_NULL; - if (NullableNotNullManager.isNullable((PsiModifierListOwner)value)) return DfaUtil.Nullness.NULL; + if (NullableNotNullManager.isNotNull((PsiModifierListOwner)value)) return Nullness.NOT_NULL; + if (NullableNotNullManager.isNullable((PsiModifierListOwner)value)) return Nullness.NULLABLE; } - if (value instanceof PsiEnumConstant) return DfaUtil.Nullness.NOT_NULL; - return DfaUtil.Nullness.UNKNOWN; + if (value instanceof PsiEnumConstant) return Nullness.NOT_NULL; + return Nullness.UNKNOWN; } public static class NullAnalysisResult { diff --git a/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java b/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java index 5c9ff9c153e4..cb62f4d47492 100644 --- a/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java +++ b/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java @@ -72,7 +72,7 @@ public class BaseGenerateTestSupportMethodAction extends BaseGenerateAction { } @Override - protected boolean isValidForFile(Project project, Editor editor, PsiFile file) { + protected boolean isValidForFile(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { if (file instanceof PsiCompiledElement) return false; PsiDocumentManager.getInstance(project).commitAllDocuments(); diff --git a/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java b/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java index 67636d5ce4ac..9e389dda012e 100644 --- a/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java +++ b/java/java-impl/src/com/intellij/testIntegration/JavaTestFramework.java @@ -108,8 +108,9 @@ public abstract class JavaTestFramework implements TestFramework { return null; } - protected PsiMethod createSetUpPatternMethod(JVMElementFactory factory) { + public PsiMethod createSetUpPatternMethod(JVMElementFactory factory) { final FileTemplate template = FileTemplateManager.getInstance().getCodeTemplate(getSetUpMethodFileTemplateDescriptor().getFileName()); - return factory.createMethodFromText(StringUtil.replace(template.getText(), "${BODY}\n", ""), null); + final String templateText = StringUtil.replace(StringUtil.replace(template.getText(), "${BODY}\n", ""), "${NAME}", "setUp"); + return factory.createMethodFromText(templateText, null); } } diff --git a/java/java-impl/src/com/intellij/testIntegration/intention/MoveInitializerToSetUpMethodAction.java b/java/java-impl/src/com/intellij/testIntegration/intention/MoveInitializerToSetUpMethodAction.java index 7d8f852942a8..fdaa574c2871 100644 --- a/java/java-impl/src/com/intellij/testIntegration/intention/MoveInitializerToSetUpMethodAction.java +++ b/java/java-impl/src/com/intellij/testIntegration/intention/MoveInitializerToSetUpMethodAction.java @@ -18,9 +18,14 @@ package com.intellij.testIntegration.intention; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.TestFrameworks; import com.intellij.codeInsight.intention.impl.BaseMoveInitializerToMethodAction; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.testIntegration.JavaTestFramework; +import com.intellij.testIntegration.TestFramework; import com.intellij.testIntegration.TestIntegrationUtils; import org.jetbrains.annotations.NotNull; @@ -32,6 +37,8 @@ import java.util.Collections; * @author cdr */ public class MoveInitializerToSetUpMethodAction extends BaseMoveInitializerToMethodAction { + private static final Logger LOG = Logger.getInstance("#" + MoveInitializerToSetUpMethodAction.class.getName()); + @Override @NotNull public String getFamilyName() { @@ -46,7 +53,27 @@ public class MoveInitializerToSetUpMethodAction extends BaseMoveInitializerToMet @Override public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { - return super.isAvailable(project, editor, element) && TestIntegrationUtils.isTest(element); + final boolean isAvailable = super.isAvailable(project, editor, element) && TestIntegrationUtils.isTest(element); + if (isAvailable) { + final PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class); + LOG.assertTrue(field != null); + final PsiClass aClass = field.getContainingClass(); + LOG.assertTrue(aClass != null); + final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); + for (TestFramework framework : Extensions.getExtensions(TestFramework.EXTENSION_NAME)) { + if (framework instanceof JavaTestFramework && framework.isTestClass(aClass)) { + try { + ((JavaTestFramework)framework).createSetUpPatternMethod(elementFactory); + return true; + } + catch (Exception e) { + return false; + } + } + } + return true; + } + return false; } @NotNull diff --git a/java/java-impl/src/com/intellij/util/xml/JvmPsiTypeConverterImpl.java b/java/java-impl/src/com/intellij/util/xml/JvmPsiTypeConverterImpl.java index a7eabd13ad4d..9c1eae2971f8 100644 --- a/java/java-impl/src/com/intellij/util/xml/JvmPsiTypeConverterImpl.java +++ b/java/java-impl/src/com/intellij/util/xml/JvmPsiTypeConverterImpl.java @@ -86,7 +86,7 @@ public class JvmPsiTypeConverterImpl extends JvmPsiTypeConverter implements Cust if (Arrays.binarySearch(CanonicalPsiTypeConverterImpl.PRIMITIVES, s) >= 0) { return JavaPsiFacade.getInstance(context.getProject()).getElementFactory().createPrimitiveType(s); } - final PsiClass aClass1 = DomJavaUtil.findClass(s, context.getFile(), context.getModule(), null); + final PsiClass aClass1 = DomJavaUtil.findClass(s, context.getFile(), context.getModule(), context.getSearchScope()); return aClass1 == null ? null : createType(aClass1); } diff --git a/java/java-impl/src/com/intellij/util/xml/PsiClassConverter.java b/java/java-impl/src/com/intellij/util/xml/PsiClassConverter.java index 27b71df5d6d3..a5b0cf2698c3 100644 --- a/java/java-impl/src/com/intellij/util/xml/PsiClassConverter.java +++ b/java/java-impl/src/com/intellij/util/xml/PsiClassConverter.java @@ -43,7 +43,7 @@ public class PsiClassConverter extends Converter<PsiClass> implements CustomRefe public static PsiClass findClass(String s, ConvertContext context) { final DomElement element = context.getInvocationElement(); - final GlobalSearchScope scope = element instanceof GenericDomValue ? getSearchScope(context) : null; + final GlobalSearchScope scope = element instanceof GenericDomValue ? context.getSearchScope() : null; return DomJavaUtil.findClass(s, context.getFile(), context.getModule(), scope); } @@ -64,7 +64,8 @@ public class PsiClassConverter extends Converter<PsiClass> implements CustomRefe return provider.getReferencesByElement(element); } - protected JavaClassReferenceProvider createClassReferenceProvider(final GenericDomValue<PsiClass> genericDomValue, final ConvertContext context, + protected JavaClassReferenceProvider createClassReferenceProvider(final GenericDomValue<PsiClass> genericDomValue, + final ConvertContext context, ExtendClass extendClass) { return createJavaClassReferenceProvider(genericDomValue, extendClass, new JavaClassReferenceProvider() { @@ -99,7 +100,6 @@ public class PsiClassConverter extends Converter<PsiClass> implements CustomRefe provider.setOption(JavaClassReferenceProvider.JVM_FORMAT, Boolean.TRUE); } provider.setAllowEmpty(extendClass.allowEmpty()); - } ClassTemplate template = genericDomValue.getAnnotation(ClassTemplate.class); @@ -114,22 +114,9 @@ public class PsiClassConverter extends Converter<PsiClass> implements CustomRefe return provider; } - public static GlobalSearchScope getSearchScope(@NotNull ConvertContext context) { - final Module module = context.getModule(); - if (module == null) return null; - PsiFile file = context.getFile(); - file = file.getOriginalFile(); - VirtualFile virtualFile = file.getVirtualFile(); - if (virtualFile == null) return null; - ProjectFileIndex fileIndex = ProjectRootManager.getInstance(file.getProject()).getFileIndex(); - boolean tests = fileIndex.isInTestSourceContent(virtualFile); - return module.getModuleRuntimeScope(tests); - - } - @Nullable - protected GlobalSearchScope getScope(@NotNull ConvertContext context) { - return getSearchScope(context); + protected GlobalSearchScope getScope(@NotNull ConvertContext context) { + return context.getSearchScope(); } public static class AnnotationType extends PsiClassConverter { diff --git a/java/java-impl/src/resources/projectTemplates/Java/Command_Line_App.zip b/java/java-impl/src/resources/projectTemplates/Java/Command_Line_App.zip Binary files differindex 055660651364..b87acb2a00f2 100644 --- a/java/java-impl/src/resources/projectTemplates/Java/Command_Line_App.zip +++ b/java/java-impl/src/resources/projectTemplates/Java/Command_Line_App.zip diff --git a/java/java-indexing-impl/src/com/intellij/codeInsight/ReadableExternalAnnotationsManager.java b/java/java-indexing-impl/src/com/intellij/codeInsight/ReadableExternalAnnotationsManager.java index 727f4a2e1e0c..bba288fe937b 100644 --- a/java/java-indexing-impl/src/com/intellij/codeInsight/ReadableExternalAnnotationsManager.java +++ b/java/java-indexing-impl/src/com/intellij/codeInsight/ReadableExternalAnnotationsManager.java @@ -52,19 +52,20 @@ public class ReadableExternalAnnotationsManager extends BaseExternalAnnotationsM return myHasAnyAnnotationsRoots == ThreeState.YES; } - @NotNull @Override + @NotNull protected List<VirtualFile> getExternalAnnotationsRoots(@NotNull VirtualFile libraryFile) { - final List<OrderEntry> entries = ProjectRootManager.getInstance(myPsiManager.getProject()).getFileIndex().getOrderEntriesForFile( - libraryFile); + ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myPsiManager.getProject()).getFileIndex(); + List<OrderEntry> entries = fileIndex.getOrderEntriesForFile(libraryFile); List<VirtualFile> result = new ArrayList<VirtualFile>(); + VirtualFileManager vfManager = VirtualFileManager.getInstance(); for (OrderEntry entry : entries) { if (entry instanceof ModuleOrderEntry) { continue; } final String[] externalUrls = AnnotationOrderRootType.getUrls(entry); for (String url : externalUrls) { - VirtualFile root = VirtualFileManager.getInstance().findFileByUrl(url); + VirtualFile root = vfManager.findFileByUrl(url); if (root != null) { result.add(root); } diff --git a/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java b/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java index dd339ffc4cef..8ca2c256b23b 100644 --- a/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java +++ b/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -58,7 +58,8 @@ public interface CommonClassNames { @NonNls String JAVA_UTIL_DICTIONARY = "java.util.Dictionary"; @NonNls String JAVA_UTIL_COMPARATOR = "java.util.Comparator"; - @NonNls String JAVA_SQL_DATE = "java.sql.Date"; + /** @deprecated not that common (to remove in IDEA 13) */ + @SuppressWarnings("UnusedDeclaration") @NonNls String JAVA_SQL_DATE = "java.sql.Date"; @NonNls String JAVA_IO_SERIALIZABLE = "java.io.Serializable"; @NonNls String JAVA_IO_EXTERNALIZABLE = "java.io.Externalizable"; @@ -87,10 +88,11 @@ public interface CommonClassNames { @NonNls String JAVA_UTIL_ARRAY_LIST = "java.util.ArrayList"; @NonNls String JAVA_LANG_INVOKE_MH_POLYMORPHIC = "java.lang.invoke.MethodHandle.PolymorphicSignature"; - String TARGET_ANNOTATION_FQ_NAME = "java.lang.annotation.Target"; + @NonNls String TARGET_ANNOTATION_FQ_NAME = "java.lang.annotation.Target"; @NonNls String JAVA_LANG_RUNNABLE = "java.lang.Runnable"; @NonNls String JAVA_IO_FILE = "java.io.File"; - String JAVA_LANG_ASSERTION_ERROR = "java.lang.AssertionError"; + @NonNls String JAVA_LANG_ASSERTION_ERROR = "java.lang.AssertionError"; @NonNls String JAVA_UTIL_CONCURRENT_CALLABLE = "java.util.concurrent.Callable"; @NonNls String JAVA_UTIL_MAP_ENTRY = "java.util.Map.Entry"; + @NonNls String JAVA_UTIL_HASH_MAP = "java.util.HashMap"; } diff --git a/java/java-psi-api/src/com/intellij/psi/JavaResolveResult.java b/java/java-psi-api/src/com/intellij/psi/JavaResolveResult.java index 397fdf5f958e..320a69c19f25 100644 --- a/java/java-psi-api/src/com/intellij/psi/JavaResolveResult.java +++ b/java/java-psi-api/src/com/intellij/psi/JavaResolveResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ package com.intellij.psi; /** * JavaResolveResult holds additional information that is obtained - * when Java references are being resolved + * when Java references are being resolved. * * @author ik, dsl * @see com.intellij.psi.PsiCall#resolveMethodGenerics() @@ -26,8 +26,7 @@ public interface JavaResolveResult extends ResolveResult { JavaResolveResult[] EMPTY_ARRAY = new JavaResolveResult[0]; /** - * Substitutor providing values of type parameters occuring - * in {@link #getElement()}. + * Substitutor providing values of type parameters occurring in {@link #getElement()}. */ PsiSubstitutor getSubstitutor(); @@ -35,34 +34,24 @@ public interface JavaResolveResult extends ResolveResult { /** * @return true if {@link #getElement()} is accessible from reference. - * */ boolean isAccessible(); boolean isStaticsScopeCorrect(); /** - * @return scope in the reference's file where the reference has been resolved - * null for qualified and local references + * @return scope in the reference's file where the reference has been resolved, + * {@code null} for qualified and local references. */ PsiElement getCurrentFileResolveScope(); - - JavaResolveResult EMPTY = new JavaResolveResult(){ - @Override - public PsiElement getElement(){return null;} - @Override - public PsiSubstitutor getSubstitutor(){return PsiSubstitutor.EMPTY;} - @Override - public boolean isValidResult(){return false;} - @Override - public boolean isAccessible(){return false;} - @Override - public boolean isStaticsScopeCorrect(){return false;} - @Override - public PsiElement getCurrentFileResolveScope() { return null; } - - @Override - public boolean isPackagePrefixPackageReference() { return false; } + JavaResolveResult EMPTY = new JavaResolveResult() { + @Override public PsiElement getElement() { return null; } + @Override public PsiSubstitutor getSubstitutor() { return PsiSubstitutor.EMPTY; } + @Override public boolean isValidResult() { return false; } + @Override public boolean isAccessible() { return false; } + @Override public boolean isStaticsScopeCorrect() { return false; } + @Override public PsiElement getCurrentFileResolveScope() { return null; } + @Override public boolean isPackagePrefixPackageReference() { return false; } }; }
\ No newline at end of file diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index 9a5303ed4417..5214e3eb0cfa 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -17,12 +17,15 @@ package com.intellij.psi; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pair; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.util.*; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,6 +38,7 @@ import java.util.*; public class LambdaUtil { private static final Logger LOG = Logger.getInstance("#" + LambdaUtil.class.getName()); public static ThreadLocal<Set<PsiParameterList>> ourParams = new ThreadLocal<Set<PsiParameterList>>(); + @NonNls public static final String JAVA_LANG_FUNCTIONAL_INTERFACE = "java.lang.FunctionalInterface"; @Nullable public static PsiType getFunctionalInterfaceReturnType(PsiLambdaExpression expr) { @@ -109,13 +113,29 @@ public class LambdaUtil { while (parent instanceof PsiParenthesizedExpression) { parent = parent.getParent(); } - if (parent instanceof PsiExpressionList && functionalInterfaceType instanceof PsiClassType && ((PsiClassType)functionalInterfaceType).isRaw()){ - return false; + if (parent instanceof PsiExpressionList) { + final PsiElement gParent = parent.getParent(); + if (gParent instanceof PsiMethodCallExpression) { + final PsiExpression qualifierExpression = ((PsiMethodCallExpression)gParent).getMethodExpression().getQualifierExpression(); + final PsiType type = qualifierExpression != null ? qualifierExpression.getType() : null; + if (type instanceof PsiClassType && ((PsiClassType)type).isRaw()) { + return true; + } + } + if (functionalInterfaceType instanceof PsiClassType && ((PsiClassType)functionalInterfaceType).isRaw()){ + return false; + } } return true; } public static boolean isAcceptable(PsiLambdaExpression lambdaExpression, final PsiType leftType, boolean checkReturnType) { + if (leftType instanceof PsiIntersectionType) { + for (PsiType conjunctType : ((PsiIntersectionType)leftType).getConjuncts()) { + if (isAcceptable(lambdaExpression, conjunctType, checkReturnType)) return true; + } + return false; + } final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(leftType); final PsiClass psiClass = resolveResult.getElement(); if (psiClass instanceof PsiAnonymousClass) { @@ -462,17 +482,16 @@ public class LambdaUtil { if (type == null) { type = getFunctionalInterfaceType(lambdaExpression, false); } - final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(type); - if (resolveResult != null) { - final PsiMethod method = getFunctionalInterfaceMethod(type); - if (method != null) { - final PsiParameter[] parameters = method.getParameterList().getParameters(); - if (parameterIndex < parameters.length) { - final PsiType psiType = getSubstitutor(method, resolveResult).substitute(parameters[parameterIndex].getType()); - if (!dependsOnTypeParams(psiType, type, lambdaExpression, null)) { - return GenericsUtil.eliminateWildcards(psiType); - } - } + if (type instanceof PsiIntersectionType) { + final PsiType[] conjuncts = ((PsiIntersectionType)type).getConjuncts(); + for (PsiType conjunct : conjuncts) { + final PsiType lambdaParameterFromType = getLambdaParameterFromType(parameterIndex, lambdaExpression, conjunct); + if (lambdaParameterFromType != null) return lambdaParameterFromType; + } + } else { + final PsiType lambdaParameterFromType = getLambdaParameterFromType(parameterIndex, lambdaExpression, type); + if (lambdaParameterFromType != null) { + return lambdaParameterFromType; } } } @@ -485,6 +504,23 @@ public class LambdaUtil { return new PsiLambdaParameterType(param); } + private static PsiType getLambdaParameterFromType(int parameterIndex, PsiLambdaExpression lambdaExpression, PsiType conjunct) { + final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(conjunct); + if (resolveResult != null) { + final PsiMethod method = getFunctionalInterfaceMethod(conjunct); + if (method != null) { + final PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameterIndex < parameters.length) { + final PsiType psiType = getSubstitutor(method, resolveResult).substitute(parameters[parameterIndex].getType()); + if (!dependsOnTypeParams(psiType, conjunct, lambdaExpression, null)) { + return GenericsUtil.eliminateWildcards(psiType); + } + } + } + } + return null; + } + public static PsiSubstitutor inferFromReturnType(final PsiTypeParameter[] typeParameters, final PsiType returnType, @Nullable final PsiType interfaceMethodReturnType, @@ -557,6 +593,104 @@ public class LambdaUtil { return result; } + public static void checkMoreSpecificReturnType(List<CandidateInfo> conflicts, int functionalInterfaceIdx) { + final CandidateInfo[] newConflictsArray = conflicts.toArray(new CandidateInfo[conflicts.size()]); + for (int i = 1; i < newConflictsArray.length; i++) { + final CandidateInfo method = newConflictsArray[i]; + final PsiType interfaceReturnType = getReturnType(functionalInterfaceIdx, method); + for (int j = 0; j < i; j++) { + final CandidateInfo conflict = newConflictsArray[j]; + assert conflict != method; + final PsiType interfaceReturnType1 = getReturnType(functionalInterfaceIdx, conflict); + if (interfaceReturnType != null && interfaceReturnType1 != null && !Comparing.equal(interfaceReturnType, interfaceReturnType1)) { + int moreSpecific = isMoreSpecific(interfaceReturnType, interfaceReturnType1); + if (moreSpecific > 0) { + conflicts.remove(method); + break; + } + else if (moreSpecific < 0) { + conflicts.remove(conflict); + } + } + } + } + } + + private static int isMoreSpecific(PsiType returnType, PsiType returnType1) { + if (returnType == PsiType.VOID || returnType1 == PsiType.VOID) return 0; + if (returnType instanceof PsiPrimitiveType) { + if (!(returnType1 instanceof PsiPrimitiveType)) { + return -1; + } else { + return TypeConversionUtil.areTypesConvertible(returnType, returnType1) ? 1 : -1; + } + } + if (returnType1 instanceof PsiPrimitiveType) { + return 1; + } + + final PsiClassType.ClassResolveResult r = PsiUtil.resolveGenericsClassInType(returnType); + final PsiClass rClass = r.getElement(); + final PsiClassType.ClassResolveResult r1 = PsiUtil.resolveGenericsClassInType(returnType1); + final PsiClass rClass1 = r1.getElement(); + if (rClass != null && rClass1 != null) { + if (rClass == rClass1) { + int moreSpecific = 0; + for (PsiTypeParameter parameter : rClass.getTypeParameters()) { + final PsiType t = r.getSubstitutor().substituteWithBoundsPromotion(parameter); + final PsiType t1 = r1.getSubstitutor().substituteWithBoundsPromotion(parameter); + if (t == null || t1 == null) continue; + if (t1.isAssignableFrom(t) && !GenericsUtil.eliminateWildcards(t1).equals(t)) { + if (moreSpecific == 1) { + return 0; + } + moreSpecific = -1; + } + else if (t.isAssignableFrom(t1) && !GenericsUtil.eliminateWildcards(t).equals(t1)) { + if (moreSpecific == -1) { + return 0; + } + moreSpecific = 1; + } + else { + return 0; + } + } + return moreSpecific; + } + else if (rClass1.isInheritor(rClass, true)) { + return 1; + } + else if (rClass.isInheritor(rClass1, true)) { + return -1; + } + } + return 0; + } + + @Nullable + private static PsiType getReturnType(int functionalTypeIdx, CandidateInfo method) { + final PsiParameter[] methodParameters = ((PsiMethod)method.getElement()).getParameterList().getParameters(); + if (methodParameters.length == 0) return null; + final PsiParameter param = functionalTypeIdx < methodParameters.length ? methodParameters[functionalTypeIdx] : methodParameters[methodParameters.length - 1]; + final PsiType functionalInterfaceType = method.getSubstitutor().substitute(param.getType()); + return getFunctionalInterfaceReturnType(functionalInterfaceType); + } + + @Nullable + public static String checkFunctionalInterface(PsiAnnotation annotation) { + if (PsiUtil.isLanguageLevel8OrHigher(annotation) && Comparing.strEqual(annotation.getQualifiedName(), JAVA_LANG_FUNCTIONAL_INTERFACE)) { + final PsiAnnotationOwner owner = annotation.getOwner(); + if (owner instanceof PsiModifierList) { + final PsiElement parent = ((PsiModifierList)owner).getParent(); + if (parent instanceof PsiClass) { + return LambdaHighlightingUtil.checkInterfaceFunctional((PsiClass)parent); + } + } + } + return null; + } + static class TypeParamsChecker extends PsiTypeVisitor<Boolean> { private PsiMethod myMethod; private final PsiClass myClass; diff --git a/java/java-psi-api/src/com/intellij/psi/PsiElementFinder.java b/java/java-psi-api/src/com/intellij/psi/PsiElementFinder.java index 7638a64265cd..41bb666bf429 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiElementFinder.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiElementFinder.java @@ -99,6 +99,9 @@ public abstract class PsiElementFinder { return PsiClass.EMPTY_ARRAY; } + /** + * A method to optimize resolve (to only search classes in a package which might be there) + */ @NotNull public Set<String> getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) { return getClassNames(getClasses(psiPackage, scope)); diff --git a/java/java-psi-api/src/com/intellij/psi/PsiJavaReference.java b/java/java-psi-api/src/com/intellij/psi/PsiJavaReference.java index c2c69e9f25b8..c6e92a3c3727 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiJavaReference.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiJavaReference.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -45,5 +45,4 @@ public interface PsiJavaReference extends PsiPolyVariantReference { @Override @NotNull JavaResolveResult[] multiResolve(boolean incompleteCode); - } diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java index 1d01037048bb..635f4ce4539a 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java @@ -16,9 +16,7 @@ package com.intellij.psi; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.Comparing; import com.intellij.psi.codeStyle.JavaCodeStyleManager; -import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.MethodSignature; import com.intellij.psi.util.PsiUtil; @@ -26,7 +24,6 @@ import com.intellij.psi.util.TypeConversionUtil; import org.jetbrains.annotations.Nullable; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -116,6 +113,12 @@ public class PsiMethodReferenceUtil { public static boolean isAcceptable(@Nullable final PsiMethodReferenceExpression methodReferenceExpression, PsiType left) { if (methodReferenceExpression == null) return false; + if (left instanceof PsiIntersectionType) { + for (PsiType conjunct : ((PsiIntersectionType)left).getConjuncts()) { + if (isAcceptable(methodReferenceExpression, conjunct)) return true; + } + return false; + } Map<PsiMethodReferenceExpression, PsiType> map = ourRefs.get(); if (map == null) { map = new HashMap<PsiMethodReferenceExpression, PsiType>(); @@ -240,7 +243,7 @@ public class PsiMethodReferenceUtil { final int min = Math.min(signatureParameterTypes2.length, signatureParameterTypes1.length); for (int i = 0; i < min; i++) { - final PsiType type1 = psiSubstitutor.substitute(GenericsUtil.eliminateWildcards(signatureParameterTypes1[offset + i])); + final PsiType type1 = GenericsUtil.eliminateWildcards(psiSubstitutor.substitute(signatureParameterTypes1[offset + i])); if (isVarargs && i == min - 1) { if (!TypeConversionUtil.isAssignable(((PsiArrayType)signatureParameterTypes2[i]).getComponentType(), type1) && !TypeConversionUtil.isAssignable(signatureParameterTypes2[i], type1)) { @@ -248,7 +251,7 @@ public class PsiMethodReferenceUtil { } } else { - if (!TypeConversionUtil.isAssignable(signatureParameterTypes2[i], psiSubstitutor.substitute(GenericsUtil.eliminateWildcards(type1)))) { + if (!TypeConversionUtil.isAssignable(signatureParameterTypes2[i], type1)) { return false; } } @@ -266,76 +269,4 @@ public class PsiMethodReferenceUtil { methodReferenceExpression); return (PsiLocalVariable)((PsiDeclarationStatement)assignmentFromText).getDeclaredElements()[0]; } - - public static void processMethodReferenceReturnType(List<CandidateInfo> conflicts, int functionalInterfaceIdx) { - final CandidateInfo[] newConflictsArray = conflicts.toArray(new CandidateInfo[conflicts.size()]); - for (int i = 1; i < newConflictsArray.length; i++) { - final CandidateInfo method = newConflictsArray[i]; - final PsiType interfaceReturnType = getReturnType(functionalInterfaceIdx, method); - for (int j = 0; j < i; j++) { - final CandidateInfo conflict = newConflictsArray[j]; - assert conflict != method; - final PsiType interfaceReturnType1 = getReturnType(functionalInterfaceIdx, conflict); - if (interfaceReturnType != null && interfaceReturnType1 != null && !Comparing.equal(interfaceReturnType, interfaceReturnType1)) { - int moreSpecific = isMoreSpecific(interfaceReturnType, interfaceReturnType1); - if (moreSpecific > 0) { - conflicts.remove(method); - break; - } - else if (moreSpecific < 0) { - conflicts.remove(conflict); - } - } - } - } - } - - private static int isMoreSpecific(PsiType returnType, PsiType returnType1) { - final PsiClassType.ClassResolveResult r = PsiUtil.resolveGenericsClassInType(returnType); - final PsiClass rClass = r.getElement(); - final PsiClassType.ClassResolveResult r1 = PsiUtil.resolveGenericsClassInType(returnType1); - final PsiClass rClass1 = r1.getElement(); - if (rClass != null && rClass1 != null) { - if (rClass == rClass1) { - int moreSpecific = 0; - for (PsiTypeParameter parameter : rClass.getTypeParameters()) { - final PsiType t = r.getSubstitutor().substituteWithBoundsPromotion(parameter); - final PsiType t1 = r1.getSubstitutor().substituteWithBoundsPromotion(parameter); - if (t == null || t1 == null) continue; - if (t1.isAssignableFrom(t) && !GenericsUtil.eliminateWildcards(t1).equals(t)) { - if (moreSpecific == 1) { - return 0; - } - moreSpecific = -1; - } - else if (t.isAssignableFrom(t1) && !GenericsUtil.eliminateWildcards(t).equals(t1)) { - if (moreSpecific == -1) { - return 0; - } - moreSpecific = 1; - } - else { - return 0; - } - } - return moreSpecific; - } - else if (rClass1.isInheritor(rClass, true)) { - return 1; - } - else if (rClass.isInheritor(rClass1, true)) { - return -1; - } - } - return 0; - } - - @Nullable - private static PsiType getReturnType(int functionalTypeIdx, CandidateInfo method) { - final PsiParameter[] methodParameters = ((PsiMethod)method.getElement()).getParameterList().getParameters(); - if (methodParameters.length == 0) return null; - final PsiParameter param = functionalTypeIdx < methodParameters.length ? methodParameters[functionalTypeIdx] : methodParameters[methodParameters.length - 1]; - final PsiType functionalInterfaceType = method.getSubstitutor().substitute(param.getType()); - return LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType); - } } diff --git a/java/java-psi-api/src/com/intellij/psi/augment/PsiAugmentProvider.java b/java/java-psi-api/src/com/intellij/psi/augment/PsiAugmentProvider.java index 23d4d4fa25f6..a105f446f288 100644 --- a/java/java-psi-api/src/com/intellij/psi/augment/PsiAugmentProvider.java +++ b/java/java-psi-api/src/com/intellij/psi/augment/PsiAugmentProvider.java @@ -17,7 +17,6 @@ package com.intellij.psi.augment; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; @@ -35,11 +34,8 @@ public abstract class PsiAugmentProvider { public static <Psi extends PsiElement> List<Psi> collectAugments(@NotNull final PsiElement element, @NotNull final Class<Psi> type) { final List<Psi> augments = new ArrayList<Psi>(); for (PsiAugmentProvider provider : Extensions.getExtensions(EP_NAME)) { - try { - final List<Psi> list = provider.getAugments(element, type); - augments.addAll(list); - } - catch (ProcessCanceledException ignore) { } + final List<Psi> list = provider.getAugments(element, type); + augments.addAll(list); } return augments; diff --git a/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/DefaultParameterTypeInferencePolicy.java b/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/DefaultParameterTypeInferencePolicy.java index c964036edfaf..aeb83e4f4cd4 100644 --- a/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/DefaultParameterTypeInferencePolicy.java +++ b/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/DefaultParameterTypeInferencePolicy.java @@ -27,7 +27,7 @@ public class DefaultParameterTypeInferencePolicy extends ParameterTypeInferenceP @Nullable @Override - public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiCallExpression innerMethodCall, + public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiExpression innerMethodCall, PsiExpressionList parent, PsiCallExpression contextCall, PsiTypeParameter typeParameter) { diff --git a/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/ParameterTypeInferencePolicy.java b/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/ParameterTypeInferencePolicy.java index e50133b99fb8..780232a4e59f 100644 --- a/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/ParameterTypeInferencePolicy.java +++ b/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/ParameterTypeInferencePolicy.java @@ -24,7 +24,7 @@ import org.jetbrains.annotations.Nullable; */ public abstract class ParameterTypeInferencePolicy { @Nullable - public abstract Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiCallExpression innerMethodCall, + public abstract Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiExpression innerMethodCall, PsiExpressionList parent, PsiCallExpression contextCall, PsiTypeParameter typeParameter); diff --git a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java index 8126582654f0..8c6f4c4ed477 100644 --- a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java +++ b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java @@ -41,7 +41,6 @@ public class MethodCandidateInfo extends CandidateInfo{ private final PsiType[] myTypeArguments; private PsiSubstitutor myCalcedSubstitutor = null; private final LanguageLevel myLanguageLevel; - private static final Object LOCK = new Object(); public MethodCandidateInfo(PsiElement candidate, PsiSubstitutor substitutor, @@ -99,27 +98,11 @@ public class MethodCandidateInfo extends CandidateInfo{ PsiSubstitutor incompleteSubstitutor = super.getSubstitutor(); PsiMethod method = getElement(); if (myTypeArguments == null) { - Map<PsiElement, Pair<PsiMethod, PsiSubstitutor>> map; - synchronized (LOCK) { - map = CURRENT_CANDIDATE.get(); - if (map == null) { - map = new ConcurrentWeakHashMap<PsiElement, Pair<PsiMethod, PsiSubstitutor>>(); - CURRENT_CANDIDATE.set(map); - } - } - map.put(myArgumentList, Pair.create(getElement(), incompleteSubstitutor)); - try { - - final Set<PsiParameterList> lists = LambdaUtil.ourParams.get(); - if (lists != null && !lists.isEmpty()) { + final Set<PsiParameterList> lists = LambdaUtil.ourParams.get(); + if (lists != null && !lists.isEmpty()) { return inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE); - } - - myCalcedSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE); - } - finally { - map.remove(myArgumentList); - } + } + myCalcedSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE); } else { PsiTypeParameter[] typeParams = method.getTypeParameters(); @@ -165,21 +148,32 @@ public class MethodCandidateInfo extends CandidateInfo{ } public PsiSubstitutor inferTypeArguments(final ParameterTypeInferencePolicy policy, final PsiExpression[] arguments) { - PsiMethod method = getElement(); - PsiTypeParameter[] typeParameters = method.getTypeParameters(); - - JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(method.getProject()); - if (!method.hasModifierProperty(PsiModifier.STATIC)) { - final PsiClass containingClass = method.getContainingClass(); - if (containingClass != null && PsiUtil.isRawSubstitutor(containingClass, mySubstitutor)) { - return javaPsiFacade.getElementFactory().createRawSubstitutor(mySubstitutor, typeParameters); - } + Map<PsiElement, Pair<PsiMethod, PsiSubstitutor>> map = CURRENT_CANDIDATE.get(); + if (map == null) { + map = new ConcurrentWeakHashMap<PsiElement, Pair<PsiMethod, PsiSubstitutor>>(); + CURRENT_CANDIDATE.set(map); } + final PsiMethod method = getElement(); + final Pair<PsiMethod, PsiSubstitutor> alreadyThere = map.put(myArgumentList, Pair.create(method, super.getSubstitutor())); + try { + PsiTypeParameter[] typeParameters = method.getTypeParameters(); + + JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(method.getProject()); + if (!method.hasModifierProperty(PsiModifier.STATIC)) { + final PsiClass containingClass = method.getContainingClass(); + if (containingClass != null && PsiUtil.isRawSubstitutor(containingClass, mySubstitutor)) { + return javaPsiFacade.getElementFactory().createRawSubstitutor(mySubstitutor, typeParameters); + } + } - final PsiElement parent = getParent(); - if (parent == null) return PsiSubstitutor.EMPTY; - return javaPsiFacade.getResolveHelper() - .inferTypeArguments(typeParameters, method.getParameterList().getParameters(), arguments, mySubstitutor, parent, policy); + final PsiElement parent = getParent(); + if (parent == null) return PsiSubstitutor.EMPTY; + return javaPsiFacade.getResolveHelper() + .inferTypeArguments(typeParameters, method.getParameterList().getParameters(), arguments, mySubstitutor, parent, policy); + } + finally { + if (alreadyThere == null) map.remove(myArgumentList); + } } public boolean isInferencePossible() { diff --git a/java/java-psi-api/src/com/intellij/psi/util/ClassUtil.java b/java/java-psi-api/src/com/intellij/psi/util/ClassUtil.java index d7f8aa2a27c2..158e7dd81a16 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/ClassUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/ClassUtil.java @@ -244,7 +244,7 @@ public class ClassUtil { } @Nullable - public static String getJVMClassName(PsiClass aClass) { + public static String getJVMClassName(@NotNull PsiClass aClass) { final PsiClass containingClass = aClass.getContainingClass(); if (containingClass != null) { String parentName = getJVMClassName(containingClass); diff --git a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java index 72c373ec94a5..f97ff1736c8d 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java @@ -202,7 +202,7 @@ public class MethodSignatureUtil { if (checkDeep) { final PsiClass clazz = superClass.getSuperClass(); - if (clazz != null) { + if (clazz != null && clazz != superClass) { PsiSubstitutor substitutor1 = TypeConversionUtil.getSuperClassSubstitutor(clazz, superClass, superSubstitutor); return doFindMethodInSuperClassBySignatureInDerived(clazz, substitutor1, signature, true); } diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java index 08b8deb0f0e4..3d6f4c7f5be5 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java @@ -431,6 +431,20 @@ public class PsiFormatUtil extends PsiFormatUtilBase { } public static String getPackageDisplayName(@NotNull final PsiClass psiClass) { + if (psiClass instanceof PsiTypeParameter) { + PsiTypeParameterListOwner owner = ((PsiTypeParameter)psiClass).getOwner(); + String ownerName = null; + if (owner instanceof PsiClass) { + ownerName = ((PsiClass)owner).getQualifiedName(); + if (ownerName == null) { + ownerName = owner.getName(); + } + } else if (owner instanceof PsiMethod) { + ownerName = owner.getName(); + } + return ownerName == null ? "type parameter" : "type parameter of " + ownerName; + } + @NonNls String packageName = psiClass.getQualifiedName(); packageName = packageName == null || packageName.lastIndexOf('.') <= 0 ? "" : packageName.substring(0, packageName.lastIndexOf('.')); if (packageName.isEmpty()) { diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java index c0d120fcf0d1..a206a642e396 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java @@ -667,9 +667,7 @@ public class TypeConversionUtil { if (right instanceof PsiMethodReferenceType) { final PsiMethodReferenceExpression methodReferenceExpression = ((PsiMethodReferenceType)right).getExpression(); - if (left instanceof PsiClassType) { - return PsiMethodReferenceUtil.isAcceptable(methodReferenceExpression, (PsiClassType)left); - } else if (left instanceof PsiLambdaExpressionType) { + if (left instanceof PsiLambdaExpressionType) { final PsiType rType = methodReferenceExpression.getFunctionalInterfaceType(); final PsiType lType = ((PsiLambdaExpressionType)left).getExpression().getFunctionalInterfaceType(); return Comparing.equal(rType, lType); @@ -678,18 +676,17 @@ public class TypeConversionUtil { final PsiType lType = ((PsiMethodReferenceType)left).getExpression().getFunctionalInterfaceType(); return Comparing.equal(rType, lType); } + return PsiMethodReferenceUtil.isAcceptable(methodReferenceExpression, left); } if (right instanceof PsiLambdaExpressionType) { final PsiLambdaExpression rLambdaExpression = ((PsiLambdaExpressionType)right).getExpression(); - if (left instanceof PsiClassType) { - return LambdaUtil.isAcceptable(rLambdaExpression, left, false); - } if (left instanceof PsiLambdaExpressionType) { final PsiLambdaExpression lLambdaExpression = ((PsiLambdaExpressionType)left).getExpression(); final PsiType rType = rLambdaExpression.getFunctionalInterfaceType(); final PsiType lType = lLambdaExpression.getFunctionalInterfaceType(); return Comparing.equal(rType, lType); } + return LambdaUtil.isAcceptable(rLambdaExpression, left, false); } if (left instanceof PsiIntersectionType) { diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java index b09ed08510af..4c5d3181d2bc 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java @@ -15,21 +15,26 @@ */ package com.intellij.codeInsight; +import com.intellij.lang.PsiBuilder; +import com.intellij.lang.java.parser.JavaParser; +import com.intellij.lang.java.parser.JavaParserUtil; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.io.StreamUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; +import com.intellij.psi.impl.source.*; import com.intellij.psi.util.PsiFormatUtil; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.ConcurrencyUtil; +import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; -import com.intellij.util.containers.ConcurrentSoftHashMap; -import com.intellij.util.containers.ConcurrentSoftValueHashMap; -import com.intellij.util.containers.MultiMap; -import gnu.trove.THashMap; +import com.intellij.util.SmartList; +import com.intellij.util.containers.*; +import gnu.trove.THashSet; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; @@ -40,11 +45,11 @@ import java.io.IOException; import java.util.*; import java.util.concurrent.ConcurrentMap; -public abstract class BaseExternalAnnotationsManager extends ExternalAnnotationsManager{ - private static final Logger LOG = Logger.getInstance("#" + BaseExternalAnnotationsManager.class.getName()); - @NotNull private static final List<PsiFile> NULL = new ArrayList<PsiFile>(); - @NotNull protected final ConcurrentMap<String, List<PsiFile>> - myExternalAnnotations = new ConcurrentSoftValueHashMap<String, List<PsiFile>>(); +public abstract class BaseExternalAnnotationsManager extends ExternalAnnotationsManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.BaseExternalAnnotationsManager"); + @NotNull private static final List<PsiFile> NULL_LIST = new ArrayList<PsiFile>(0); + @NotNull + private final ConcurrentMap<String, List<PsiFile>> myExternalAnnotations = new ConcurrentSoftValueHashMap<String, List<PsiFile>>(10, 0.75f, 2); protected final PsiManager myPsiManager; public BaseExternalAnnotationsManager(final PsiManager psiManager) { @@ -57,7 +62,7 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations } @Nullable - protected static String getFQN(@NotNull String packageName, @NotNull PsiFile psiFile) { + private static String getFQN(@NotNull String packageName, @NotNull PsiFile psiFile) { VirtualFile virtualFile = psiFile.getVirtualFile(); if (virtualFile == null) return null; return StringUtil.getQualifiedName(packageName, virtualFile.getNameWithoutExtension()); @@ -78,16 +83,26 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations } final int idx = externalName.indexOf('('); if (idx == -1) return externalName; - StringBuilder buf = new StringBuilder(); + StringBuilder buf = new StringBuilder(externalName.length()); int rightIdx = externalName.indexOf(')'); String[] params = externalName.substring(idx + 1, rightIdx).split(","); - buf.append(externalName.substring(0, idx + 1)); + buf.append(externalName, 0, idx + 1); for (String param : params) { param = param.trim(); - final int spaceIdx = param.indexOf(' '); - buf.append(spaceIdx > -1 ? param.substring(0, spaceIdx) : param).append(", "); + int spaceIdx = param.indexOf(' '); + if (spaceIdx > -1) { + buf.append(param, 0, spaceIdx); + } + else { + buf.append(param); + } + buf.append(", "); + } + if (StringUtil.endsWith(buf, ", ")) { + buf.delete(buf.length() - ", ".length(), buf.length()); } - return StringUtil.trimEnd(buf.toString(), ", ") + externalName.substring(rightIdx); + buf.append(externalName, rightIdx, externalName.length()); + return buf.toString(); } protected abstract boolean hasAnyAnnotationsRoots(); @@ -95,73 +110,153 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations @Override @Nullable public PsiAnnotation findExternalAnnotation(@NotNull final PsiModifierListOwner listOwner, @NotNull final String annotationFQN) { - return collectExternalAnnotations(listOwner).get(annotationFQN); + List<AnnotationData> list = collectExternalAnnotations(listOwner); + AnnotationData data = findByFQN(list, annotationFQN); + return data == null ? null : data.getAnnotation(); } @Override - public boolean isExternalAnnotationWritable(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN) { + public boolean isExternalAnnotationWritable(@NotNull PsiModifierListOwner listOwner, @NotNull final String annotationFQN) { // note that this method doesn't cache it's result - Map<String, PsiAnnotation> map = doCollect(listOwner, true); - return map.containsKey(annotationFQN); + List<AnnotationData> map = doCollect(listOwner, true); + return findByFQN(map, annotationFQN) != null; + } + + private static AnnotationData findByFQN(@NotNull List<AnnotationData> map, @NotNull final String annotationFQN) { + return ContainerUtil.find(map, new Condition<AnnotationData>() { + @Override + public boolean value(AnnotationData data) { + return data.annotationClassFqName.equals(annotationFQN); + } + }); } @Override @Nullable public PsiAnnotation[] findExternalAnnotations(@NotNull final PsiModifierListOwner listOwner) { - final Map<String, PsiAnnotation> result = collectExternalAnnotations(listOwner); - return result.isEmpty() ? null : result.values().toArray(new PsiAnnotation[result.size()]); + final List<AnnotationData> result = collectExternalAnnotations(listOwner); + return result.isEmpty() ? null : ContainerUtil.map2Array(result, PsiAnnotation.EMPTY_ARRAY, new Function<AnnotationData, PsiAnnotation>() { + @Override + public PsiAnnotation fun(AnnotationData data) { + return data.getAnnotation(); + } + }); } - private final ConcurrentMap<PsiModifierListOwner, Map<String, PsiAnnotation>> cache = new ConcurrentSoftHashMap<PsiModifierListOwner, Map<String, PsiAnnotation>>(); + private static final List<AnnotationData> NO_DATA = new ArrayList<AnnotationData>(1); + private final ConcurrentMostlySingularMultiMap<PsiModifierListOwner, AnnotationData> cache = new ConcurrentMostlySingularMultiMap<PsiModifierListOwner, AnnotationData>(); + private final CharTableImpl charTable = new CharTableImpl(); @NotNull - private Map<String, PsiAnnotation> collectExternalAnnotations(@NotNull final PsiModifierListOwner listOwner) { - if (!hasAnyAnnotationsRoots()) return Collections.emptyMap(); + private List<AnnotationData> collectExternalAnnotations(@NotNull PsiModifierListOwner listOwner) { + if (!hasAnyAnnotationsRoots()) return Collections.emptyList(); + + List<AnnotationData> cached; + while (true) { + cached = (List<AnnotationData>)cache.get(listOwner); + if (cached == NO_DATA || !cached.isEmpty()) return cached; + List<AnnotationData> computed = doCollect(listOwner, false); + if (cache.replace(listOwner, cached, computed)) { + cached = computed; + break; + } + } + return cached; + } - Map<String, PsiAnnotation> map = cache.get(listOwner); - if (map == null) { - map = doCollect(listOwner, false); - map = ConcurrencyUtil.cacheOrGet(cache, listOwner, map); + private final Map<AnnotationData, AnnotationData> annotationDataCache = new WeakKeyWeakValueHashMap<AnnotationData, AnnotationData>(); + @NotNull + private AnnotationData internAnnotationData(@NotNull AnnotationData data) { + synchronized (annotationDataCache) { + AnnotationData interned = annotationDataCache.get(data); + if (interned == null) { + annotationDataCache.put(data, data); + interned = data; + } + return interned; } - return map; } - private final ConcurrentMap<PsiFile, Pair<MultiMap<String, AnnotationData>, Long>> annotationsFileToDataAndModificationStamp = new ConcurrentSoftHashMap<PsiFile, Pair<MultiMap<String, AnnotationData>, Long>>(); + + private final ConcurrentMap<PsiFile, Pair<MostlySingularMultiMap<String, AnnotationData>, Long>> annotationFileToDataAndModStamp = new ConcurrentSoftHashMap<PsiFile, Pair<MostlySingularMultiMap<String, AnnotationData>, Long>>(); + @NotNull - private MultiMap<String, AnnotationData> getDataFromFile(@NotNull PsiFile file) { - Pair<MultiMap<String, AnnotationData>, Long> cached = annotationsFileToDataAndModificationStamp.get(file); + private MostlySingularMultiMap<String, AnnotationData> getDataFromFile(@NotNull PsiFile file) { + Pair<MostlySingularMultiMap<String, AnnotationData>, Long> cached = annotationFileToDataAndModStamp.get(file); if (cached != null && cached.getSecond() == file.getModificationStamp()) { return cached.getFirst(); } - MultiMap<String, AnnotationData> data = new MultiMap<String, AnnotationData>(); + MostlySingularMultiMap<String, AnnotationData> data = new MostlySingularMultiMap<String, AnnotationData>(); try { - VirtualFile virtualFile = file.getVirtualFile(); - if (virtualFile != null) { - Document document = JDOMUtil.loadDocument(escapeAttributes(StreamUtil.readText(virtualFile.getInputStream()))); - Element rootElement = document.getRootElement(); - if (rootElement != null) { + Document document = JDOMUtil.loadDocument(escapeAttributes(file.getText())); + Element rootElement = document.getRootElement(); + if (rootElement != null) { + boolean sorted = true; + boolean modified = false; + String prevItemName = null; + //noinspection unchecked + for (Element element : (List<Element>) rootElement.getChildren("item")) { + String externalName = element.getAttributeValue("name"); + if (externalName == null) { + element.detach(); + modified = true; + continue; + } + if (prevItemName != null && prevItemName.compareTo(externalName) > 0) { + sorted = false; + } + prevItemName = externalName; + //noinspection unchecked - for (Element element : (List<Element>) rootElement.getChildren()) { - String ownerName = element.getAttributeValue("name"); - if (ownerName == null) continue; + for (Element annotationElement : (List<Element>) element.getChildren("annotation")) { + String annotationFQN = annotationElement.getAttributeValue("name"); + if (StringUtil.isEmpty(annotationFQN)) continue; + annotationFQN = intern(annotationFQN); //noinspection unchecked - for (Element annotationElement : (List<Element>) element.getChildren()) { - String annotationFQN = annotationElement.getAttributeValue("name"); - if (StringUtil.isEmpty(annotationFQN)) continue; - StringBuilder buf = new StringBuilder(); - //noinspection unchecked - for (Element annotationParameter : (List<Element>) annotationElement.getChildren()) { + List<Element> children = (List<Element>)annotationElement.getChildren(); + StringBuilder buf = new StringBuilder(children.size() * "name=value,".length()); // just guess + for (Element annotationParameter : children) { + if (buf.length() != 0) { buf.append(","); - String nameValue = annotationParameter.getAttributeValue("name"); - if (nameValue != null) { - buf.append(nameValue).append("="); - } - buf.append(annotationParameter.getAttributeValue("val")); } - String annotationText = "@" + annotationFQN + (buf.length() > 0 ? "(" + StringUtil.trimStart(buf.toString(), ",") + ")" : ""); - data.putValue(ownerName, new AnnotationData(annotationFQN, annotationText)); + String nameValue = annotationParameter.getAttributeValue("name"); + if (nameValue != null) { + buf.append(nameValue); + buf.append("="); + } + buf.append(annotationParameter.getAttributeValue("val")); } + String annotationParameters = buf.length() == 0 ? "" : intern(buf.toString()); + for (AnnotationData existingData : data.get(externalName)) { + if (existingData.annotationClassFqName.equals(annotationFQN)) { + LOG.error("Duplicate annotation '" + annotationFQN+"' for signature: '" + externalName + "' in the file " + file.getVirtualFile().getPresentableUrl()); + } + } + AnnotationData annData = internAnnotationData(new AnnotationData(annotationFQN, annotationParameters)); + + data.add(externalName, annData); } } + if (!sorted) { + modified = true; + List<Element> items = new ArrayList<Element>(rootElement.getChildren("item")); + rootElement.removeChildren("item"); + Collections.sort(items, new Comparator<Element>() { + @Override + public int compare(Element item1, Element item2) { + String externalName1 = item1.getAttributeValue("name"); + String externalName2 = item2.getAttributeValue("name"); + return externalName1.compareTo(externalName2); + } + }); + for (Element item : items) { + rootElement.addContent(item); + } + } + VirtualFile virtualFile = file.getVirtualFile(); + if (modified && virtualFile.isInLocalFileSystem() && virtualFile.isWritable()) { + String lineSeparator = FileDocumentManager.getInstance().getLineSeparator(virtualFile, file.getProject()); + JDOMUtil.writeDocument(document, virtualFile.getPath(), lineSeparator); + } } } catch (IOException e) { @@ -171,58 +266,74 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations LOG.error(e); } if (data.isEmpty()) { - data = MultiMap.emptyInstance(); + data = MostlySingularMultiMap.emptyMap(); } - Pair<MultiMap<String, AnnotationData>, Long> pair = Pair.create(data, file.getModificationStamp()); - pair = ConcurrencyUtil.cacheOrGet(annotationsFileToDataAndModificationStamp, file, pair); - data = pair.first; + data.compact(); + Pair<MostlySingularMultiMap<String, AnnotationData>, Long> pair = Pair.create(data, file.getModificationStamp()); + annotationFileToDataAndModStamp.put(file, pair); return data; } @NotNull - private Map<String, PsiAnnotation> doCollect(@NotNull PsiModifierListOwner listOwner, boolean onlyWritable) { + private String intern(@NotNull String annotationFQN) { + return charTable.doIntern(annotationFQN).toString(); + } + + @NotNull + private List<AnnotationData> doCollect(@NotNull PsiModifierListOwner listOwner, boolean onlyWritable) { final List<PsiFile> files = findExternalAnnotationsFiles(listOwner); if (files == null) { - return Collections.emptyMap(); + return NO_DATA; } - Map<String, PsiAnnotation> result = new THashMap<String, PsiAnnotation>(); + SmartList<AnnotationData> result = new SmartList<AnnotationData>(); String externalName = getExternalName(listOwner, false); + if (externalName == null) return NO_DATA; String oldExternalName = getNormalizedExternalName(listOwner); - final PsiElementFactory factory = JavaPsiFacade.getInstance(myPsiManager.getProject()).getElementFactory(); for (PsiFile file : files) { if (!file.isValid()) continue; if (onlyWritable && !file.isWritable()) continue; - final MultiMap<String, AnnotationData> fileData = getDataFromFile(file); + MostlySingularMultiMap<String, AnnotationData> fileData = getDataFromFile(file); - collectAnnotations(result, fileData.get(externalName), factory); - collectAnnotations(result, fileData.get(oldExternalName), factory); + Collection<AnnotationData> data = (Collection<AnnotationData>)fileData.get(externalName); + for (AnnotationData ad : data) { + if (result.contains(ad)) { + LOG.error("Duplicate signature:\n" + externalName + "; in " + toVirtualFiles(files)); + } + else { + result.add(ad); + } + } + if (oldExternalName != null && !externalName.equals(oldExternalName)) { + Collection<AnnotationData> oldCollection = (Collection<AnnotationData>)fileData.get(oldExternalName); + for (AnnotationData ad : oldCollection) { + if (result.contains(ad)) { + LOG.error("Duplicate signature o:\n" + oldExternalName + "; in " + toVirtualFiles(files)); + } + else { + result.add(ad); + } + } + } + } + if (result.isEmpty()) { + return NO_DATA; } + result.trimToSize(); return result; } - private static void collectAnnotations(Map<String, PsiAnnotation> result, - Collection<AnnotationData> dataCollection, - PsiElementFactory factory) { - for (AnnotationData annotationData : dataCollection) { - // don't add annotation, if there already is one with this FQ name - if (result.containsKey(annotationData.annotationClassFqName)) continue; - - try { - PsiAnnotation annotation = factory.createAnnotationFromText(annotationData.annotationText, null); - result.put(annotationData.annotationClassFqName, annotation); - } - catch (IncorrectOperationException e) { - LOG.error(e); + static List<VirtualFile> toVirtualFiles(List<PsiFile> files) { + return ContainerUtil.map(files, new Function<PsiFile, VirtualFile>() { + @Override + public VirtualFile fun(PsiFile file) { + return file.getVirtualFile(); } - } + }); } - @NotNull - protected abstract List<VirtualFile> getExternalAnnotationsRoots(@NotNull VirtualFile libraryFile); - @Override @Nullable public List<PsiFile> findExternalAnnotationsFiles(@NotNull PsiModifierListOwner listOwner) { @@ -236,7 +347,7 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations String fqn = getFQN(packageName, containingFile); if (fqn == null) return null; final List<PsiFile> files = myExternalAnnotations.get(fqn); - if (files == NULL) return null; + if (files == NULL_LIST) return null; if (files != null) { boolean allValid = true; for (PsiFile file : files) { @@ -251,7 +362,7 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations return null; } - ArrayList<PsiFile> possibleAnnotationsXmls = new ArrayList<PsiFile>(); + Set<PsiFile> possibleAnnotationsXmls = new THashSet<PsiFile>(); for (VirtualFile root : getExternalAnnotationsRoots(virtualFile)) { final VirtualFile ext = root.findFileByRelativePath(packageName.replace(".", "/") + "/" + ANNOTATIONS_XML); if (ext == null) continue; @@ -259,10 +370,15 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations if (psiFile == null) continue; possibleAnnotationsXmls.add(psiFile); } - possibleAnnotationsXmls.trimToSize(); - if (!possibleAnnotationsXmls.isEmpty()) { + List<PsiFile> result; + if (possibleAnnotationsXmls.isEmpty()) { + myExternalAnnotations.put(fqn, NULL_LIST); + result = null; + } + else { + result = new SmartList<PsiFile>(possibleAnnotationsXmls); // sorting by writability: writable go first - Collections.sort(possibleAnnotationsXmls, new Comparator<PsiFile>() { + Collections.sort(result, new Comparator<PsiFile>() { @Override public int compare(PsiFile f1, PsiFile f2) { boolean w1 = f1.isWritable(); @@ -274,16 +390,17 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations } }); - myExternalAnnotations.put(fqn, possibleAnnotationsXmls); - return possibleAnnotationsXmls; + myExternalAnnotations.put(fqn, result); } - myExternalAnnotations.put(fqn, NULL); - return null; + return result; } + @NotNull + protected abstract List<VirtualFile> getExternalAnnotationsRoots(@NotNull VirtualFile libraryFile); + protected void dropCache() { myExternalAnnotations.clear(); - annotationsFileToDataAndModificationStamp.clear(); + annotationFileToDataAndModStamp.clear(); cache.clear(); } @@ -294,7 +411,7 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations private static String escapeAttributes(@NotNull String invalidXml) { // We assume that XML has single- and double-quote characters only for attribute values, therefore we don't any complex parsing, // just have binary inAttribute state - StringBuilder buf = new StringBuilder(); + StringBuilder buf = new StringBuilder(invalidXml.length()); boolean inAttribute = false; for (int i = 0; i < invalidXml.length(); i++) { char c = invalidXml.charAt(i); @@ -340,13 +457,63 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations throw new UnsupportedOperationException(); } - private static class AnnotationData { - @NotNull public String annotationClassFqName; - @NotNull public String annotationText; + protected void cacheExternalAnnotations(@NotNull String packageName, @NotNull PsiFile fromFile, @NotNull List<PsiFile> annotationFiles) { + String fqn = getFQN(packageName, fromFile); + if (fqn != null) { + myExternalAnnotations.put(fqn, annotationFiles); + } + } + + private class AnnotationData { + @NotNull private final String annotationClassFqName; + @NotNull private final String annotationParameters; + private PsiAnnotation annotation; - private AnnotationData(@NotNull String annotationClassFqName, @NotNull String annotationText) { + private AnnotationData(@NotNull String annotationClassFqName, @NotNull String annotationParameters) { this.annotationClassFqName = annotationClassFqName; - this.annotationText = annotationText; + this.annotationParameters = annotationParameters; + } + + @NotNull + private PsiAnnotation getAnnotation() { + PsiAnnotation a = annotation; + if (a == null) { + annotation = a = createAnnotationFromText("@" + annotationClassFqName + (annotationParameters.isEmpty() ? "" : "("+annotationParameters+")")); + } + return a; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AnnotationData data = (AnnotationData)o; + + return annotationClassFqName.equals(data.annotationClassFqName) && annotationParameters.equals(data.annotationParameters); + } + + @Override + public int hashCode() { + int result = annotationClassFqName.hashCode(); + result = 31 * result + annotationParameters.hashCode(); + return result; + } + } + + @NotNull + private PsiAnnotation createAnnotationFromText(@NotNull final String text) throws IncorrectOperationException { + final DummyHolder holder = DummyHolderFactory.createHolder(myPsiManager, new JavaDummyElement(text, ANNOTATION, LanguageLevel.HIGHEST), null, charTable); + final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); + if (!(element instanceof PsiAnnotation)) { + throw new IncorrectOperationException("Incorrect annotation \"" + text + "\"."); } + return (PsiAnnotation)element; } + private static final JavaParserUtil.ParserWrapper ANNOTATION = new JavaParserUtil.ParserWrapper() { + @Override + public void parse(final PsiBuilder builder) { + JavaParser.INSTANCE.getDeclarationParser().parseAnnotation(builder); + } + }; } diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java index 1707915b8804..f78ee83b570a 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java @@ -17,12 +17,9 @@ package com.intellij.codeInsight; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.NullableComputable; import com.intellij.psi.*; import com.intellij.psi.controlFlow.*; import com.intellij.psi.impl.PsiImplUtil; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.search.ProjectScope; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; @@ -240,6 +237,9 @@ public class ExceptionUtil { PsiCallExpression expression = (PsiCallExpression)element; unhandledExceptions = getUnhandledExceptions(expression, topElement, includeSelfCalls); } + else if (element instanceof PsiMethodReferenceExpression) { + unhandledExceptions = getUnhandledExceptions((PsiMethodReferenceExpression)element, topElement); + } else if (element instanceof PsiThrowStatement) { PsiThrowStatement statement = (PsiThrowStatement)element; unhandledExceptions = getUnhandledExceptions(statement, topElement); @@ -310,6 +310,16 @@ public class ExceptionUtil { return foundExceptions; } + private static Collection<PsiClassType> getUnhandledExceptions(PsiMethodReferenceExpression methodReferenceExpression, + PsiElement topElement) { + final JavaResolveResult resolveResult = methodReferenceExpression.advancedResolve(false); + final PsiElement resolve = resolveResult.getElement(); + if (resolve instanceof PsiMethod) { + return getUnhandledExceptions((PsiMethod)resolve, methodReferenceExpression, topElement, resolveResult.getSubstitutor()); + } + return Collections.emptyList(); + } + private static boolean firstStatementIsConstructorCall(PsiCodeBlock constructorBody) { final PsiStatement[] statements = constructorBody.getStatements(); if (statements.length == 0) return false; @@ -338,6 +348,12 @@ public class ExceptionUtil { } @Override + public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) { + addExceptions(array, getUnhandledExceptions(expression, null)); + visitElement(expression); + } + + @Override public void visitResourceVariable(PsiResourceVariable resourceVariable) { addExceptions(array, getUnhandledCloserExceptions(resourceVariable, null)); visitElement(resourceVariable); @@ -472,12 +488,17 @@ public class ExceptionUtil { } private static boolean isArrayClone(PsiMethod method, PsiElement element) { - if (!(element instanceof PsiMethodCallExpression)) return false; if (!method.getName().equals(CLONE_METHOD_NAME)) return false; PsiClass containingClass = method.getContainingClass(); if (containingClass == null || !CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())) { return false; } + if (element instanceof PsiMethodReferenceExpression) { + final PsiMethodReferenceExpression methodCallExpression = (PsiMethodReferenceExpression)element; + final PsiExpression qualifierExpression = methodCallExpression.getQualifierExpression(); + return qualifierExpression != null && qualifierExpression.getType() instanceof PsiArrayType; + } + if (!(element instanceof PsiMethodCallExpression)) return false; PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)element; final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression(); @@ -485,35 +506,7 @@ public class ExceptionUtil { } public static boolean isUncheckedException(@NotNull PsiClassType type) { - final PsiClass aClass = type.resolve(); - if (aClass == null) return false; - - final GlobalSearchScope searchScope = ProjectScope.getLibrariesScope(aClass.getProject()); - final PsiClass runtimeExceptionClass = ApplicationManager.getApplication().runReadAction( - new NullableComputable<PsiClass>() { - @Override - public PsiClass compute() { - return JavaPsiFacade.getInstance(aClass.getProject()).findClass(CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION, searchScope); - } - } - ); - if (runtimeExceptionClass != null && InheritanceUtil.isInheritorOrSelf(aClass, runtimeExceptionClass, true)) { - return true; - } - - final PsiClass errorClass = ApplicationManager.getApplication().runReadAction( - new NullableComputable<PsiClass>() { - @Override - public PsiClass compute() { - return JavaPsiFacade.getInstance(aClass.getProject()).findClass(CommonClassNames.JAVA_LANG_ERROR, searchScope); - } - } - ); - if (errorClass != null && InheritanceUtil.isInheritorOrSelf(aClass, errorClass, true)) { - return true; - } - - return false; + return InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION) || InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_LANG_ERROR); } public static boolean isUncheckedExceptionOrSuperclass(@NotNull final PsiClassType type) { @@ -545,7 +538,12 @@ public class ExceptionUtil { return parent instanceof PsiAnonymousClass && isHandled(parent, exceptionType, topElement); } else if (parent instanceof PsiLambdaExpression) { - return true; + final PsiType interfaceType = ((PsiLambdaExpression)parent).getFunctionalInterfaceType(); + return isDeclaredBySAMMethod(exceptionType, interfaceType); + } + else if (element instanceof PsiMethodReferenceExpression) { + final PsiType interfaceType = ((PsiMethodReferenceExpression)element).getFunctionalInterfaceType(); + return isDeclaredBySAMMethod(exceptionType, interfaceType); } else if (parent instanceof PsiClassInitializer) { if (((PsiClassInitializer)parent).hasModifierProperty(PsiModifier.STATIC)) return false; @@ -592,6 +590,16 @@ public class ExceptionUtil { return isHandled(parent, exceptionType, topElement); } + private static boolean isDeclaredBySAMMethod(PsiClassType exceptionType, PsiType interfaceType) { + if (interfaceType != null) { + final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(interfaceType); + if (interfaceMethod != null) { + return isHandledByMethodThrowsClause(interfaceMethod, exceptionType); + } + } + return true; + } + private static boolean areAllConstructorsThrow(final PsiClass aClass, PsiClassType exceptionType) { if (aClass == null) return false; final PsiMethod[] constructors = aClass.getConstructors(); diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index 0b2397f4e1df..dca78ce60d56 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -467,7 +467,7 @@ public class JavaDocInfoGenerator { } // not a javadoc in fact.. - private void generateVariableJavaDoc(@NonNls StringBuilder buffer, PsiVariable variable, boolean generatePrologueAndEpilogue) { + private static void generateVariableJavaDoc(@NonNls StringBuilder buffer, PsiVariable variable, boolean generatePrologueAndEpilogue) { if (generatePrologueAndEpilogue) generatePrologue(buffer); @@ -604,7 +604,7 @@ public class JavaDocInfoGenerator { } } - private void generateAnnotations (@NonNls StringBuilder buffer, PsiModifierListOwner owner) { + private static void generateAnnotations(@NonNls StringBuilder buffer, PsiModifierListOwner owner) { final PsiModifierList ownerModifierList = owner.getModifierList(); if (ownerModifierList == null) return; PsiAnnotation[] annotations = ownerModifierList.getAnnotations(); @@ -1861,5 +1861,10 @@ public class JavaDocInfoGenerator { public void visitLiteralExpression(PsiLiteralExpression expression) { myBuffer.append(expression.getText()); } + + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { + myBuffer.append(expression.getText()); + } } } diff --git a/java/java-psi-impl/src/com/intellij/core/CoreJavaFileManager.java b/java/java-psi-impl/src/com/intellij/core/CoreJavaFileManager.java index 41dda61bab85..1df60969e17e 100644 --- a/java/java-psi-impl/src/com/intellij/core/CoreJavaFileManager.java +++ b/java/java-psi-impl/src/com/intellij/core/CoreJavaFileManager.java @@ -139,16 +139,27 @@ public class CoreJavaFileManager implements JavaFileManager { PsiClass curClass = classes[0]; if (bucks > 0) { - while (true) { - int b = className.indexOf("$"); + int newComponentStart = 0; + int lookupStart = 0; - String component = b < 0 ? className : className.substring(0, b); + while (lookupStart <= className.length()) { + int b = className.indexOf("$", lookupStart); + b = b < 0 ? className.length(): b; + + String component = className.substring(newComponentStart, b); PsiClass inner = curClass.findInnerClassByName(component, false); - if (inner == null) return null; + lookupStart = b + 1; + if (inner == null) { + continue; + } + + newComponentStart = lookupStart; curClass = inner; - className = className.substring(b + 1); - if (b < 0) break; + } + + if (lookupStart != newComponentStart) { + return null; } } diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java index 42a5fafe3309..2dbc3f18edca 100644 --- a/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java +++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java @@ -549,10 +549,13 @@ public class ExpressionParser { final PsiBuilder.Marker mark = builder.mark(); final ReferenceParser.TypeInfo typeInfo = myParser.getReferenceParser().parseTypeInfo(builder, 0); - if (typeInfo != null && (typeInfo.isPrimitive || !typeInfo.hasErrors && typeInfo.isParameterized)) { - final PsiBuilder.Marker result = continueClassAccessOrMethodReference(builder, mark, typeInfo.isPrimitive); - if (result != null) { - return result; + if (typeInfo != null) { + boolean optionalClassKeyword = typeInfo.isPrimitive || typeInfo.isArray; + if (optionalClassKeyword || !typeInfo.hasErrors && typeInfo.isParameterized) { + final PsiBuilder.Marker result = continueClassAccessOrMethodReference(builder, mark, optionalClassKeyword); + if (result != null) { + return result; + } } } @@ -776,10 +779,10 @@ public class ExpressionParser { @Nullable private PsiBuilder.Marker continueClassAccessOrMethodReference(final PsiBuilder builder, final PsiBuilder.Marker expr, - final boolean primitive) { + final boolean optionalClassKeyword) { final IElementType tokenType = builder.getTokenType(); if (tokenType == JavaTokenType.DOT) { - return parseClassObjectAccess(builder, expr, primitive); + return parseClassObjectAccess(builder, expr, optionalClassKeyword); } else if (tokenType == JavaTokenType.DOUBLE_COLON) { return parseMethodReference(builder, expr); @@ -789,7 +792,7 @@ public class ExpressionParser { } @Nullable - private static PsiBuilder.Marker parseClassObjectAccess(PsiBuilder builder, PsiBuilder.Marker expr, boolean primitive) { + private static PsiBuilder.Marker parseClassObjectAccess(PsiBuilder builder, PsiBuilder.Marker expr, boolean optionalClassKeyword) { final PsiBuilder.Marker mark = builder.mark(); builder.advanceLexer(); @@ -798,7 +801,7 @@ public class ExpressionParser { builder.advanceLexer(); } else { - if (!primitive) return null; + if (!optionalClassKeyword) return null; mark.rollbackTo(); builder.error(".class expected"); } diff --git a/java/java-psi-impl/src/com/intellij/lexer/_JavaLexer.flex b/java/java-psi-impl/src/com/intellij/lexer/_JavaLexer.flex index 5b62d45a8f4a..30413b509690 100644 --- a/java/java-psi-impl/src/com/intellij/lexer/_JavaLexer.flex +++ b/java/java-psi-impl/src/com/intellij/lexer/_JavaLexer.flex @@ -1,4 +1,18 @@ -/* It's an automatically generated code. Do not modify it. */ +/* + * Copyright 2000-2013 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.lexer; import com.intellij.pom.java.LanguageLevel; @@ -43,38 +57,24 @@ DOC_COMMENT="/*""*"+("/"|([^"/""*"]{COMMENT_TAIL}))? COMMENT_TAIL=([^"*"]*("*"+[^"*""/"])?)*("*"+"/")? END_OF_LINE_COMMENT="/""/"[^\r\n]* -DIGIT=[0-9] -DIGIT_OR_UNDERSCORE=[_0-9] -OCTAL_DIGIT=[0-7] -OCTAL_DIGIT_OR_UNDERSCORE=[_0-7] -HEX_DIGIT=[0-9A-Fa-f] -HEX_DIGIT_OR_UNDERSCORE=[_0-9A-Fa-f] -BINARY_DIGIT=[01] -BINARY_DIGIT_OR_UNDERSCORE=[_01] - -DIGITS={DIGIT}|({DIGIT}{DIGIT_OR_UNDERSCORE}*{DIGIT}) -HEX_DIGITS={HEX_DIGIT}|({HEX_DIGIT}{HEX_DIGIT_OR_UNDERSCORE}*{HEX_DIGIT}) -BINARY_DIGITS={BINARY_DIGIT}|({BINARY_DIGIT}{BINARY_DIGIT_OR_UNDERSCORE}*{BINARY_DIGIT}) - -INTEGER_LITERAL={DECIMAL_INTEGER_LITERAL}|{OCTAL_INTEGER_LITERAL}|{HEX_INTEGER_LITERAL}|{BINARY_INTEGER_LITERAL} -DECIMAL_INTEGER_LITERAL=0|([1-9]({DIGIT_OR_UNDERSCORE}*{DIGIT})?) -OCTAL_INTEGER_LITERAL=0{OCTAL_DIGIT_OR_UNDERSCORE}*{OCTAL_DIGIT} -HEX_INTEGER_LITERAL=0[Xx]{HEX_DIGITS}? -BINARY_INTEGER_LITERAL=0[Bb]{BINARY_DIGITS}? -LONG_LITERAL={INTEGER_LITERAL}[Ll] - -FLOAT_LITERAL=({FLOATING_POINT_LITERAL1}|{FLOATING_POINT_LITERAL2}|{FLOATING_POINT_LITERAL3}|{FLOATING_POINT_LITERAL4})[Ff] -DOUBLE_LITERAL=(({FLOATING_POINT_LITERAL1}|{FLOATING_POINT_LITERAL2}|{FLOATING_POINT_LITERAL3})[Dd]?)|({FLOATING_POINT_LITERAL4}[Dd]) -FLOATING_POINT_LITERAL1={DIGITS}"."{DIGITS}?{EXPONENT_PART}? -FLOATING_POINT_LITERAL2="."{DIGITS}{EXPONENT_PART}? -FLOATING_POINT_LITERAL3={DIGITS}{EXPONENT_PART} -FLOATING_POINT_LITERAL4={DIGITS} -EXPONENT_PART=[Ee]["+""-"]?{DIGITS}? - -HEX_FLOAT_LITERAL={HEX_SIGNIFICAND}{BINARY_EXPONENT}[Ff] -HEX_DOUBLE_LITERAL={HEX_SIGNIFICAND}{BINARY_EXPONENT}[Dd]? -BINARY_EXPONENT=[Pp][+-]?{DIGITS} -HEX_SIGNIFICAND={HEX_INTEGER_LITERAL}|{HEX_INTEGER_LITERAL}.|0[Xx]{HEX_DIGITS}?.{HEX_DIGITS} +DIGIT = [0-9] +DIGIT_OR_UNDERSCORE = [_0-9] +DIGITS = {DIGIT} | {DIGIT} {DIGIT_OR_UNDERSCORE}* +HEX_DIGIT_OR_UNDERSCORE = [_0-9A-Fa-f] + +INTEGER_LITERAL = {DIGITS} | {HEX_INTEGER_LITERAL} | {BIN_INTEGER_LITERAL} +LONG_LITERAL = {INTEGER_LITERAL} [Ll] +HEX_INTEGER_LITERAL = 0 [Xx] {HEX_DIGIT_OR_UNDERSCORE}* +BIN_INTEGER_LITERAL = 0 [Bb] {DIGIT_OR_UNDERSCORE}* + +FLOAT_LITERAL = ({DEC_FP_LITERAL} | {HEX_FP_LITERAL}) [Ff] | {DIGITS} [Ff] +DOUBLE_LITERAL = ({DEC_FP_LITERAL} | {HEX_FP_LITERAL}) [Dd]? | {DIGITS} [Dd] +DEC_FP_LITERAL = {DIGITS} {DEC_EXPONENT} | {DEC_SIGNIFICAND} {DEC_EXPONENT}? +DEC_SIGNIFICAND = "." {DIGITS} | {DIGITS} "." {DIGIT_OR_UNDERSCORE}* +DEC_EXPONENT = [Ee] [+-]? {DIGIT_OR_UNDERSCORE}* +HEX_FP_LITERAL = {HEX_SIGNIFICAND} {HEX_EXPONENT} +HEX_SIGNIFICAND = 0 [Xx] ({HEX_DIGIT_OR_UNDERSCORE}+ "."? | {HEX_DIGIT_OR_UNDERSCORE}* "." {HEX_DIGIT_OR_UNDERSCORE}+) +HEX_EXPONENT = [Pp] [+-]? {DIGIT_OR_UNDERSCORE}* CHARACTER_LITERAL="'"([^\\\'\r\n]|{ESCAPE_SEQUENCE})*("'"|\\)? STRING_LITERAL=\"([^\\\"\r\n]|{ESCAPE_SEQUENCE})*(\"|\\)? @@ -91,10 +91,7 @@ ESCAPE_SEQUENCE=\\[^\r\n] <YYINITIAL> {LONG_LITERAL} { return JavaTokenType.LONG_LITERAL; } <YYINITIAL> {INTEGER_LITERAL} { return JavaTokenType.INTEGER_LITERAL; } <YYINITIAL> {FLOAT_LITERAL} { return JavaTokenType.FLOAT_LITERAL; } -<YYINITIAL> {HEX_FLOAT_LITERAL} { return JavaTokenType.FLOAT_LITERAL; } <YYINITIAL> {DOUBLE_LITERAL} { return JavaTokenType.DOUBLE_LITERAL; } -<YYINITIAL> {HEX_DOUBLE_LITERAL} { return JavaTokenType.DOUBLE_LITERAL; } - <YYINITIAL> {CHARACTER_LITERAL} { return JavaTokenType.CHARACTER_LITERAL; } <YYINITIAL> {STRING_LITERAL} { return JavaTokenType.STRING_LITERAL; } diff --git a/java/java-psi-impl/src/com/intellij/lexer/_JavaLexer.java b/java/java-psi-impl/src/com/intellij/lexer/_JavaLexer.java index 702d3f66f20a..1c5711cc4c25 100644 --- a/java/java-psi-impl/src/com/intellij/lexer/_JavaLexer.java +++ b/java/java-psi-impl/src/com/intellij/lexer/_JavaLexer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -14,9 +14,7 @@ * limitations under the License. */ -/* The following code was generated by JFlex 1.4.3 on 5/14/12 1:21 PM */ - -/* It's an automatically generated code. Do not modify it. */ +/* The following code was generated by JFlex 1.4.3 on 1/17/13 8:47 PM */ package com.intellij.lexer; import com.intellij.pom.java.LanguageLevel; @@ -29,7 +27,7 @@ import com.intellij.psi.tree.IElementType; /** * This class is a scanner generated by * <a href="http://www.jflex.de/">JFlex</a> 1.4.3 - * on 5/14/12 1:21 PM from the specification file + * on 1/17/13 8:47 PM from the specification file * <tt>/home/sher/Projects/IDEA/tools/lexer/../../community/java/java-psi-impl/src/com/intellij/lexer/_JavaLexer.flex</tt> */ class _JavaLexer implements FlexLexer { @@ -53,96 +51,96 @@ class _JavaLexer implements FlexLexer { * Translates characters to character classes */ private static final String ZZ_CMAP_PACKED = - "\11\3\1\1\1\26\1\0\1\1\1\6\16\3\4\0\1\1\1\63"+ - "\1\31\1\0\1\2\1\72\1\70\1\27\1\73\1\74\1\5\1\65"+ - "\1\102\1\24\1\22\1\4\1\14\1\13\6\11\2\7\1\105\1\101"+ - "\1\66\1\62\1\67\1\104\1\106\1\12\1\16\1\12\1\21\1\23"+ - "\1\20\5\2\1\17\3\2\1\25\7\2\1\15\2\2\1\77\1\30"+ - "\1\100\1\71\1\10\1\0\1\37\1\43\1\44\1\52\1\35\1\36"+ - "\1\55\1\50\1\51\1\2\1\46\1\40\1\53\1\42\1\45\1\56"+ - "\1\2\1\33\1\41\1\32\1\34\1\57\1\60\1\54\1\47\1\61"+ - "\1\75\1\64\1\76\1\103\41\3\2\0\4\2\4\0\1\2\2\0"+ - "\1\3\7\0\1\2\4\0\1\2\5\0\27\2\1\0\37\2\1\0"+ - "\u013f\2\31\0\162\2\4\0\14\2\16\0\5\2\11\0\1\2\21\0"+ - "\130\3\5\0\23\3\12\0\1\2\13\0\1\2\1\0\3\2\1\0"+ - "\1\2\1\0\24\2\1\0\54\2\1\0\46\2\1\0\5\2\4\0"+ - "\202\2\1\0\4\3\3\0\105\2\1\0\46\2\2\0\2\2\6\0"+ - "\20\2\41\0\46\2\2\0\1\2\7\0\47\2\11\0\21\3\1\0"+ - "\27\3\1\0\3\3\1\0\1\3\1\0\2\3\1\0\1\3\13\0"+ - "\33\2\5\0\3\2\15\0\4\3\14\0\6\3\13\0\32\2\5\0"+ - "\13\2\16\3\7\0\12\3\4\0\2\2\1\3\143\2\1\0\1\2"+ - "\10\3\1\0\6\3\2\2\2\3\1\0\4\3\2\2\12\3\3\2"+ - "\2\0\1\2\17\0\1\3\1\2\1\3\36\2\33\3\2\0\3\2"+ - "\60\0\46\2\13\3\1\2\u014f\0\3\3\66\2\2\0\1\3\1\2"+ - "\20\3\2\0\1\2\4\3\3\0\12\2\2\3\2\0\12\3\21\0"+ - "\3\3\1\0\10\2\2\0\2\2\2\0\26\2\1\0\7\2\1\0"+ - "\1\2\3\0\4\2\2\0\1\3\1\2\7\3\2\0\2\3\2\0"+ - "\3\3\11\0\1\3\4\0\2\2\1\0\3\2\2\3\2\0\12\3"+ - "\4\2\15\0\3\3\1\0\6\2\4\0\2\2\2\0\26\2\1\0"+ - "\7\2\1\0\2\2\1\0\2\2\1\0\2\2\2\0\1\3\1\0"+ - "\5\3\4\0\2\3\2\0\3\3\13\0\4\2\1\0\1\2\7\0"+ - "\14\3\3\2\14\0\3\3\1\0\11\2\1\0\3\2\1\0\26\2"+ - "\1\0\7\2\1\0\2\2\1\0\5\2\2\0\1\3\1\2\10\3"+ - "\1\0\3\3\1\0\3\3\2\0\1\2\17\0\2\2\2\3\2\0"+ - "\12\3\1\0\1\2\17\0\3\3\1\0\10\2\2\0\2\2\2\0"+ - "\26\2\1\0\7\2\1\0\2\2\1\0\5\2\2\0\1\3\1\2"+ - "\6\3\3\0\2\3\2\0\3\3\10\0\2\3\4\0\2\2\1\0"+ - "\3\2\4\0\12\3\1\0\1\2\20\0\1\3\1\2\1\0\6\2"+ - "\3\0\3\2\1\0\4\2\3\0\2\2\1\0\1\2\1\0\2\2"+ - "\3\0\2\2\3\0\3\2\3\0\10\2\1\0\3\2\4\0\5\3"+ - "\3\0\3\3\1\0\4\3\11\0\1\3\17\0\11\3\11\0\1\2"+ - "\7\0\3\3\1\0\10\2\1\0\3\2\1\0\27\2\1\0\12\2"+ - "\1\0\5\2\4\0\7\3\1\0\3\3\1\0\4\3\7\0\2\3"+ - "\11\0\2\2\4\0\12\3\22\0\2\3\1\0\10\2\1\0\3\2"+ - "\1\0\27\2\1\0\12\2\1\0\5\2\2\0\1\3\1\2\7\3"+ - "\1\0\3\3\1\0\4\3\7\0\2\3\7\0\1\2\1\0\2\2"+ + "\11\3\1\1\1\6\1\0\1\1\1\6\16\3\4\0\1\1\1\60"+ + "\1\26\1\0\1\2\1\67\1\65\1\24\1\70\1\71\1\5\1\62"+ + "\1\77\1\22\1\20\1\4\1\13\11\7\1\102\1\76\1\63\1\57"+ + "\1\64\1\101\1\103\1\11\1\15\1\11\1\17\1\21\1\16\5\2"+ + "\1\12\3\2\1\23\7\2\1\14\2\2\1\74\1\25\1\75\1\66"+ + "\1\10\1\0\1\34\1\40\1\41\1\47\1\32\1\33\1\52\1\45"+ + "\1\46\1\2\1\43\1\35\1\50\1\37\1\42\1\53\1\2\1\30"+ + "\1\36\1\27\1\31\1\54\1\55\1\51\1\44\1\56\1\72\1\61"+ + "\1\73\1\100\41\3\2\0\4\2\4\0\1\2\2\0\1\3\7\0"+ + "\1\2\4\0\1\2\5\0\27\2\1\0\37\2\1\0\u013f\2\31\0"+ + "\162\2\4\0\14\2\16\0\5\2\11\0\1\2\21\0\130\3\5\0"+ + "\23\3\12\0\1\2\13\0\1\2\1\0\3\2\1\0\1\2\1\0"+ + "\24\2\1\0\54\2\1\0\46\2\1\0\5\2\4\0\202\2\1\0"+ + "\4\3\3\0\105\2\1\0\46\2\2\0\2\2\6\0\20\2\41\0"+ + "\46\2\2\0\1\2\7\0\47\2\11\0\21\3\1\0\27\3\1\0"+ + "\3\3\1\0\1\3\1\0\2\3\1\0\1\3\13\0\33\2\5\0"+ + "\3\2\15\0\4\3\14\0\6\3\13\0\32\2\5\0\13\2\16\3"+ + "\7\0\12\3\4\0\2\2\1\3\143\2\1\0\1\2\10\3\1\0"+ + "\6\3\2\2\2\3\1\0\4\3\2\2\12\3\3\2\2\0\1\2"+ + "\17\0\1\3\1\2\1\3\36\2\33\3\2\0\3\2\60\0\46\2"+ + "\13\3\1\2\u014f\0\3\3\66\2\2\0\1\3\1\2\20\3\2\0"+ + "\1\2\4\3\3\0\12\2\2\3\2\0\12\3\21\0\3\3\1\0"+ + "\10\2\2\0\2\2\2\0\26\2\1\0\7\2\1\0\1\2\3\0"+ + "\4\2\2\0\1\3\1\2\7\3\2\0\2\3\2\0\3\3\11\0"+ + "\1\3\4\0\2\2\1\0\3\2\2\3\2\0\12\3\4\2\15\0"+ + "\3\3\1\0\6\2\4\0\2\2\2\0\26\2\1\0\7\2\1\0"+ + "\2\2\1\0\2\2\1\0\2\2\2\0\1\3\1\0\5\3\4\0"+ + "\2\3\2\0\3\3\13\0\4\2\1\0\1\2\7\0\14\3\3\2"+ + "\14\0\3\3\1\0\11\2\1\0\3\2\1\0\26\2\1\0\7\2"+ + "\1\0\2\2\1\0\5\2\2\0\1\3\1\2\10\3\1\0\3\3"+ + "\1\0\3\3\2\0\1\2\17\0\2\2\2\3\2\0\12\3\1\0"+ + "\1\2\17\0\3\3\1\0\10\2\2\0\2\2\2\0\26\2\1\0"+ + "\7\2\1\0\2\2\1\0\5\2\2\0\1\3\1\2\6\3\3\0"+ + "\2\3\2\0\3\3\10\0\2\3\4\0\2\2\1\0\3\2\4\0"+ + "\12\3\1\0\1\2\20\0\1\3\1\2\1\0\6\2\3\0\3\2"+ + "\1\0\4\2\3\0\2\2\1\0\1\2\1\0\2\2\3\0\2\2"+ + "\3\0\3\2\3\0\10\2\1\0\3\2\4\0\5\3\3\0\3\3"+ + "\1\0\4\3\11\0\1\3\17\0\11\3\11\0\1\2\7\0\3\3"+ + "\1\0\10\2\1\0\3\2\1\0\27\2\1\0\12\2\1\0\5\2"+ + "\4\0\7\3\1\0\3\3\1\0\4\3\7\0\2\3\11\0\2\2"+ "\4\0\12\3\22\0\2\3\1\0\10\2\1\0\3\2\1\0\27\2"+ - "\1\0\20\2\4\0\6\3\2\0\3\3\1\0\4\3\11\0\1\3"+ - "\10\0\2\2\4\0\12\3\22\0\2\3\1\0\22\2\3\0\30\2"+ - "\1\0\11\2\1\0\1\2\2\0\7\2\3\0\1\3\4\0\6\3"+ - "\1\0\1\3\1\0\10\3\22\0\2\3\15\0\60\2\1\3\2\2"+ - "\7\3\4\0\10\2\10\3\1\0\12\3\47\0\2\2\1\0\1\2"+ - "\2\0\2\2\1\0\1\2\2\0\1\2\6\0\4\2\1\0\7\2"+ - "\1\0\3\2\1\0\1\2\1\0\1\2\2\0\2\2\1\0\4\2"+ - "\1\3\2\2\6\3\1\0\2\3\1\2\2\0\5\2\1\0\1\2"+ - "\1\0\6\3\2\0\12\3\2\0\2\2\42\0\1\2\27\0\2\3"+ - "\6\0\12\3\13\0\1\3\1\0\1\3\1\0\1\3\4\0\2\3"+ - "\10\2\1\0\42\2\6\0\24\3\1\0\2\3\4\2\4\0\10\3"+ - "\1\0\44\3\11\0\1\3\71\0\42\2\1\0\5\2\1\0\2\2"+ - "\1\0\7\3\3\0\4\3\6\0\12\3\6\0\6\2\4\3\106\0"+ - "\46\2\12\0\51\2\7\0\132\2\5\0\104\2\5\0\122\2\6\0"+ - "\7\2\1\0\77\2\1\0\1\2\1\0\4\2\2\0\7\2\1\0"+ - "\1\2\1\0\4\2\2\0\47\2\1\0\1\2\1\0\4\2\2\0"+ - "\37\2\1\0\1\2\1\0\4\2\2\0\7\2\1\0\1\2\1\0"+ - "\4\2\2\0\7\2\1\0\7\2\1\0\27\2\1\0\37\2\1\0"+ - "\1\2\1\0\4\2\2\0\7\2\1\0\47\2\1\0\23\2\16\0"+ - "\11\3\56\0\125\2\14\0\u026c\2\2\0\10\2\12\0\32\2\5\0"+ - "\113\2\3\0\3\2\17\0\15\2\1\0\4\2\3\3\13\0\22\2"+ - "\3\3\13\0\22\2\2\3\14\0\15\2\1\0\3\2\1\0\2\3"+ - "\14\0\64\2\40\3\3\0\1\2\3\0\2\2\1\3\2\0\12\3"+ - "\41\0\3\3\2\0\12\3\6\0\130\2\10\0\51\2\1\3\126\0"+ - "\35\2\3\0\14\3\4\0\14\3\12\0\12\3\36\2\2\0\5\2"+ - "\u038b\0\154\2\224\0\234\2\4\0\132\2\6\0\26\2\2\0\6\2"+ - "\2\0\46\2\2\0\6\2\2\0\10\2\1\0\1\2\1\0\1\2"+ - "\1\0\1\2\1\0\37\2\2\0\65\2\1\0\7\2\1\0\1\2"+ - "\3\0\3\2\1\0\7\2\3\0\4\2\2\0\6\2\4\0\15\2"+ - "\5\0\3\2\1\0\7\2\17\0\4\3\32\0\5\3\20\0\2\2"+ - "\23\0\1\2\13\0\4\3\6\0\6\3\1\0\1\2\15\0\1\2"+ - "\40\0\22\2\36\0\15\3\4\0\1\3\3\0\6\3\27\0\1\2"+ - "\4\0\1\2\2\0\12\2\1\0\1\2\3\0\5\2\6\0\1\2"+ - "\1\0\1\2\1\0\1\2\1\0\4\2\1\0\3\2\1\0\7\2"+ - "\3\0\3\2\5\0\5\2\26\0\44\2\u0e81\0\3\2\31\0\11\2"+ - "\6\3\1\0\5\2\2\0\5\2\4\0\126\2\2\0\2\3\2\0"+ - "\3\2\1\0\137\2\5\0\50\2\4\0\136\2\21\0\30\2\70\0"+ - "\20\2\u0200\0\u19b6\2\112\0\u51a6\2\132\0\u048d\2\u0773\0\u2ba4\2\u215c\0"+ - "\u012e\2\2\0\73\2\225\0\7\2\14\0\5\2\5\0\1\2\1\3"+ - "\12\2\1\0\15\2\1\0\5\2\1\0\1\2\1\0\2\2\1\0"+ - "\2\2\1\0\154\2\41\0\u016b\2\22\0\100\2\2\0\66\2\50\0"+ - "\15\2\3\0\20\3\20\0\4\3\17\0\2\2\30\0\3\2\31\0"+ - "\1\2\6\0\5\2\1\0\207\2\2\0\1\3\4\0\1\2\13\0"+ - "\12\3\7\0\32\2\4\0\1\2\1\0\32\2\12\0\132\2\3\0"+ - "\6\2\2\0\6\2\2\0\6\2\2\0\3\2\3\0\2\2\3\0"+ - "\2\2\22\0\3\3\4\0"; + "\1\0\12\2\1\0\5\2\2\0\1\3\1\2\7\3\1\0\3\3"+ + "\1\0\4\3\7\0\2\3\7\0\1\2\1\0\2\2\4\0\12\3"+ + "\22\0\2\3\1\0\10\2\1\0\3\2\1\0\27\2\1\0\20\2"+ + "\4\0\6\3\2\0\3\3\1\0\4\3\11\0\1\3\10\0\2\2"+ + "\4\0\12\3\22\0\2\3\1\0\22\2\3\0\30\2\1\0\11\2"+ + "\1\0\1\2\2\0\7\2\3\0\1\3\4\0\6\3\1\0\1\3"+ + "\1\0\10\3\22\0\2\3\15\0\60\2\1\3\2\2\7\3\4\0"+ + "\10\2\10\3\1\0\12\3\47\0\2\2\1\0\1\2\2\0\2\2"+ + "\1\0\1\2\2\0\1\2\6\0\4\2\1\0\7\2\1\0\3\2"+ + "\1\0\1\2\1\0\1\2\2\0\2\2\1\0\4\2\1\3\2\2"+ + "\6\3\1\0\2\3\1\2\2\0\5\2\1\0\1\2\1\0\6\3"+ + "\2\0\12\3\2\0\2\2\42\0\1\2\27\0\2\3\6\0\12\3"+ + "\13\0\1\3\1\0\1\3\1\0\1\3\4\0\2\3\10\2\1\0"+ + "\42\2\6\0\24\3\1\0\2\3\4\2\4\0\10\3\1\0\44\3"+ + "\11\0\1\3\71\0\42\2\1\0\5\2\1\0\2\2\1\0\7\3"+ + "\3\0\4\3\6\0\12\3\6\0\6\2\4\3\106\0\46\2\12\0"+ + "\51\2\7\0\132\2\5\0\104\2\5\0\122\2\6\0\7\2\1\0"+ + "\77\2\1\0\1\2\1\0\4\2\2\0\7\2\1\0\1\2\1\0"+ + "\4\2\2\0\47\2\1\0\1\2\1\0\4\2\2\0\37\2\1\0"+ + "\1\2\1\0\4\2\2\0\7\2\1\0\1\2\1\0\4\2\2\0"+ + "\7\2\1\0\7\2\1\0\27\2\1\0\37\2\1\0\1\2\1\0"+ + "\4\2\2\0\7\2\1\0\47\2\1\0\23\2\16\0\11\3\56\0"+ + "\125\2\14\0\u026c\2\2\0\10\2\12\0\32\2\5\0\113\2\3\0"+ + "\3\2\17\0\15\2\1\0\4\2\3\3\13\0\22\2\3\3\13\0"+ + "\22\2\2\3\14\0\15\2\1\0\3\2\1\0\2\3\14\0\64\2"+ + "\40\3\3\0\1\2\3\0\2\2\1\3\2\0\12\3\41\0\3\3"+ + "\2\0\12\3\6\0\130\2\10\0\51\2\1\3\126\0\35\2\3\0"+ + "\14\3\4\0\14\3\12\0\12\3\36\2\2\0\5\2\u038b\0\154\2"+ + "\224\0\234\2\4\0\132\2\6\0\26\2\2\0\6\2\2\0\46\2"+ + "\2\0\6\2\2\0\10\2\1\0\1\2\1\0\1\2\1\0\1\2"+ + "\1\0\37\2\2\0\65\2\1\0\7\2\1\0\1\2\3\0\3\2"+ + "\1\0\7\2\3\0\4\2\2\0\6\2\4\0\15\2\5\0\3\2"+ + "\1\0\7\2\17\0\4\3\32\0\5\3\20\0\2\2\23\0\1\2"+ + "\13\0\4\3\6\0\6\3\1\0\1\2\15\0\1\2\40\0\22\2"+ + "\36\0\15\3\4\0\1\3\3\0\6\3\27\0\1\2\4\0\1\2"+ + "\2\0\12\2\1\0\1\2\3\0\5\2\6\0\1\2\1\0\1\2"+ + "\1\0\1\2\1\0\4\2\1\0\3\2\1\0\7\2\3\0\3\2"+ + "\5\0\5\2\26\0\44\2\u0e81\0\3\2\31\0\11\2\6\3\1\0"+ + "\5\2\2\0\5\2\4\0\126\2\2\0\2\3\2\0\3\2\1\0"+ + "\137\2\5\0\50\2\4\0\136\2\21\0\30\2\70\0\20\2\u0200\0"+ + "\u19b6\2\112\0\u51a6\2\132\0\u048d\2\u0773\0\u2ba4\2\u215c\0\u012e\2\2\0"+ + "\73\2\225\0\7\2\14\0\5\2\5\0\1\2\1\3\12\2\1\0"+ + "\15\2\1\0\5\2\1\0\1\2\1\0\2\2\1\0\2\2\1\0"+ + "\154\2\41\0\u016b\2\22\0\100\2\2\0\66\2\50\0\15\2\3\0"+ + "\20\3\20\0\4\3\17\0\2\2\30\0\3\2\31\0\1\2\6\0"+ + "\5\2\1\0\207\2\2\0\1\3\4\0\1\2\13\0\12\3\7\0"+ + "\32\2\4\0\1\2\1\0\32\2\12\0\132\2\3\0\6\2\2\0"+ + "\6\2\2\0\6\2\2\0\3\2\3\0\2\2\3\0\2\2\22\0"+ + "\3\3\4\0"; /** * Translates characters to character classes @@ -159,28 +157,27 @@ class _JavaLexer implements FlexLexer { "\1\10\1\11\1\12\20\3\1\13\1\14\1\15\1\16"+ "\1\17\1\20\1\21\1\22\1\23\1\24\1\25\1\26"+ "\1\27\1\30\1\31\1\32\1\33\1\34\1\35\1\36"+ - "\1\37\1\40\1\41\1\42\1\43\1\0\1\44\1\45"+ - "\3\46\2\0\3\6\1\46\1\0\1\47\1\50\1\51"+ - "\2\11\2\12\34\3\1\52\3\3\1\53\6\3\1\54"+ - "\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64"+ - "\1\65\1\66\1\67\1\70\1\41\1\71\2\46\2\0"+ - "\1\6\1\44\1\0\1\6\1\0\1\72\2\3\1\73"+ - "\10\3\1\74\13\3\1\75\11\3\1\76\14\3\1\77"+ - "\1\0\2\71\4\0\1\46\2\0\1\100\2\3\1\101"+ - "\1\3\1\102\1\103\6\3\1\104\6\3\1\105\3\3"+ - "\1\106\1\3\1\107\3\3\1\110\6\3\1\111\5\3"+ - "\1\112\1\3\1\41\4\0\1\45\1\46\1\3\1\113"+ - "\2\3\1\114\1\115\1\116\4\3\1\117\1\3\1\120"+ - "\2\3\1\121\1\3\1\122\1\123\1\3\1\124\13\3"+ - "\1\125\1\3\1\126\1\127\2\3\1\130\2\3\1\131"+ - "\1\3\1\132\1\133\5\3\1\134\1\3\1\135\2\3"+ - "\1\136\3\3\1\137\1\140\3\3\1\141\4\3\1\142"+ - "\1\3\1\143\1\144\2\3\1\145\1\146\1\3\1\147"+ - "\4\3\1\150\1\151\1\3\1\152\2\3\1\153\1\3"+ - "\1\154\1\155\1\3\1\156"; + "\1\37\1\40\1\41\1\42\1\43\1\44\1\45\3\46"+ + "\2\6\1\0\1\47\1\50\1\51\2\11\2\12\34\3"+ + "\1\52\3\3\1\53\6\3\1\54\1\55\1\56\1\57"+ + "\1\60\1\61\1\62\1\63\1\64\1\65\1\66\1\67"+ + "\1\70\1\41\1\71\1\46\1\6\1\0\1\72\2\3"+ + "\1\73\10\3\1\74\13\3\1\75\11\3\1\76\14\3"+ + "\1\77\1\0\2\71\1\0\1\100\2\3\1\101\1\3"+ + "\1\102\1\103\6\3\1\104\6\3\1\105\3\3\1\106"+ + "\1\3\1\107\3\3\1\110\6\3\1\111\5\3\1\112"+ + "\1\3\1\41\1\0\1\3\1\113\2\3\1\114\1\115"+ + "\1\116\4\3\1\117\1\3\1\120\2\3\1\121\1\3"+ + "\1\122\1\123\1\3\1\124\13\3\1\125\1\3\1\126"+ + "\1\127\2\3\1\130\2\3\1\131\1\3\1\132\1\133"+ + "\5\3\1\134\1\3\1\135\2\3\1\136\3\3\1\137"+ + "\1\140\3\3\1\141\4\3\1\142\1\3\1\143\1\144"+ + "\2\3\1\145\1\146\1\3\1\147\4\3\1\150\1\151"+ + "\1\3\1\152\2\3\1\153\1\3\1\154\1\155\1\3"+ + "\1\156"; private static int [] zzUnpackAction() { - int [] result = new int[342]; + int [] result = new int[320]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -205,52 +202,49 @@ class _JavaLexer implements FlexLexer { private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = - "\0\0\0\107\0\216\0\325\0\u011c\0\u0163\0\u01aa\0\u01f1"+ - "\0\u0238\0\u027f\0\u02c6\0\u030d\0\u0354\0\u039b\0\u03e2\0\u0429"+ - "\0\u0470\0\u04b7\0\u04fe\0\u0545\0\u058c\0\u05d3\0\u061a\0\u0661"+ - "\0\u06a8\0\u06ef\0\u0736\0\u077d\0\u07c4\0\u080b\0\u0852\0\u0899"+ - "\0\u08e0\0\107\0\u0927\0\u096e\0\u09b5\0\107\0\107\0\107"+ - "\0\107\0\107\0\107\0\107\0\107\0\107\0\107\0\u09fc"+ - "\0\107\0\u0a43\0\u0a8a\0\107\0\107\0\u0ad1\0\107\0\107"+ - "\0\107\0\u0b18\0\u0b5f\0\u0ba6\0\u0bed\0\u0c34\0\u0c7b\0\u0cc2"+ - "\0\u0d09\0\u0d50\0\107\0\107\0\107\0\107\0\u0d97\0\u0dde"+ - "\0\107\0\u0e25\0\u0e6c\0\u0eb3\0\u0efa\0\u0f41\0\u0f88\0\u0fcf"+ - "\0\u1016\0\u105d\0\u10a4\0\u10eb\0\u1132\0\u1179\0\u11c0\0\u1207"+ - "\0\u124e\0\u1295\0\u12dc\0\u1323\0\u136a\0\u13b1\0\u13f8\0\u143f"+ - "\0\u1486\0\u14cd\0\u1514\0\u155b\0\u15a2\0\325\0\u15e9\0\u1630"+ - "\0\u1677\0\u16be\0\u1705\0\u174c\0\u1793\0\u17da\0\u1821\0\u1868"+ - "\0\107\0\107\0\107\0\107\0\107\0\107\0\107\0\u18af"+ - "\0\107\0\107\0\107\0\107\0\107\0\u18f6\0\u193d\0\u1984"+ - "\0\u19cb\0\u1a12\0\u1a59\0\u1aa0\0\u1a59\0\u1ae7\0\u1b2e\0\u1b75"+ - "\0\107\0\u1bbc\0\u1c03\0\325\0\u1c4a\0\u1c91\0\u1cd8\0\u1d1f"+ - "\0\u1d66\0\u1dad\0\u1df4\0\u1e3b\0\325\0\u1e82\0\u1ec9\0\u1f10"+ - "\0\u1f57\0\u1f9e\0\u1fe5\0\u202c\0\u2073\0\u20ba\0\u2101\0\u2148"+ - "\0\325\0\u218f\0\u21d6\0\u221d\0\u2264\0\u22ab\0\u22f2\0\u2339"+ - "\0\u2380\0\u23c7\0\u240e\0\u2455\0\u249c\0\u24e3\0\u252a\0\u2571"+ - "\0\u25b8\0\u25ff\0\u2646\0\u268d\0\u26d4\0\u271b\0\u2762\0\107"+ - "\0\u27a9\0\u27f0\0\107\0\u2837\0\u287e\0\u28c5\0\u290c\0\u2953"+ - "\0\u299a\0\u29e1\0\325\0\u2a28\0\u2a6f\0\325\0\u2ab6\0\325"+ - "\0\325\0\u2afd\0\u2b44\0\u2b8b\0\u2bd2\0\u2c19\0\u2c60\0\325"+ - "\0\u2ca7\0\u2cee\0\u2d35\0\u2d7c\0\u2dc3\0\u2e0a\0\325\0\u2e51"+ - "\0\u2e98\0\u2edf\0\325\0\u2f26\0\325\0\u2f6d\0\u2fb4\0\u2ffb"+ - "\0\325\0\u3042\0\u3089\0\u30d0\0\u3117\0\u315e\0\u31a5\0\325"+ - "\0\u31ec\0\u3233\0\u327a\0\u32c1\0\u3308\0\325\0\u334f\0\107"+ - "\0\u3396\0\u33dd\0\u3424\0\u346b\0\u287e\0\u287e\0\u34b2\0\u34f9"+ - "\0\u3540\0\u3587\0\325\0\325\0\u35ce\0\u3615\0\u365c\0\u36a3"+ - "\0\u36ea\0\325\0\u3731\0\325\0\u3778\0\u37bf\0\325\0\u3806"+ - "\0\325\0\325\0\u384d\0\325\0\u3894\0\u38db\0\u3922\0\u3969"+ - "\0\u39b0\0\u39f7\0\u3a3e\0\u3a85\0\u3acc\0\u3b13\0\u3b5a\0\325"+ - "\0\u3ba1\0\325\0\325\0\u3be8\0\u3c2f\0\325\0\u3c76\0\u3cbd"+ - "\0\325\0\u3d04\0\325\0\325\0\u3d4b\0\u3d92\0\u3dd9\0\u3e20"+ - "\0\u3e67\0\325\0\u3eae\0\325\0\u3ef5\0\u3f3c\0\325\0\u3f83"+ - "\0\u3fca\0\u4011\0\325\0\325\0\u4058\0\u409f\0\u40e6\0\325"+ - "\0\u412d\0\u4174\0\u41bb\0\u4202\0\325\0\u4249\0\325\0\325"+ - "\0\u4290\0\u42d7\0\325\0\325\0\u431e\0\325\0\u4365\0\u43ac"+ - "\0\u43f3\0\u443a\0\325\0\325\0\u4481\0\325\0\u44c8\0\u450f"+ - "\0\325\0\u4556\0\325\0\325\0\u459d\0\325"; + "\0\0\0\104\0\210\0\314\0\u0110\0\u0154\0\u0198\0\u01dc"+ + "\0\u0220\0\u0264\0\u02a8\0\u02ec\0\u0330\0\u0374\0\u03b8\0\u03fc"+ + "\0\u0440\0\u0484\0\u04c8\0\u050c\0\u0550\0\u0594\0\u05d8\0\u061c"+ + "\0\u0660\0\u06a4\0\u06e8\0\u072c\0\u0770\0\u07b4\0\u07f8\0\u083c"+ + "\0\u0880\0\104\0\u08c4\0\u0908\0\u094c\0\104\0\104\0\104"+ + "\0\104\0\104\0\104\0\104\0\104\0\104\0\104\0\u0990"+ + "\0\104\0\u09d4\0\u0a18\0\104\0\104\0\104\0\104\0\104"+ + "\0\u0a5c\0\u0aa0\0\u0ae4\0\u0b28\0\u0b6c\0\104\0\104\0\104"+ + "\0\104\0\u0bb0\0\u0bf4\0\104\0\u0c38\0\u0c7c\0\u0cc0\0\u0d04"+ + "\0\u0d48\0\u0d8c\0\u0dd0\0\u0e14\0\u0e58\0\u0e9c\0\u0ee0\0\u0f24"+ + "\0\u0f68\0\u0fac\0\u0ff0\0\u1034\0\u1078\0\u10bc\0\u1100\0\u1144"+ + "\0\u1188\0\u11cc\0\u1210\0\u1254\0\u1298\0\u12dc\0\u1320\0\u1364"+ + "\0\314\0\u13a8\0\u13ec\0\u1430\0\u1474\0\u14b8\0\u14fc\0\u1540"+ + "\0\u1584\0\u15c8\0\u160c\0\104\0\104\0\104\0\104\0\104"+ + "\0\104\0\104\0\u1650\0\104\0\104\0\104\0\104\0\104"+ + "\0\u1694\0\u16d8\0\u171c\0\u1760\0\u17a4\0\104\0\u17e8\0\u182c"+ + "\0\314\0\u1870\0\u18b4\0\u18f8\0\u193c\0\u1980\0\u19c4\0\u1a08"+ + "\0\u1a4c\0\314\0\u1a90\0\u1ad4\0\u1b18\0\u1b5c\0\u1ba0\0\u1be4"+ + "\0\u1c28\0\u1c6c\0\u1cb0\0\u1cf4\0\u1d38\0\314\0\u1d7c\0\u1dc0"+ + "\0\u1e04\0\u1e48\0\u1e8c\0\u1ed0\0\u1f14\0\u1f58\0\u1f9c\0\u1fe0"+ + "\0\u2024\0\u2068\0\u20ac\0\u20f0\0\u2134\0\u2178\0\u21bc\0\u2200"+ + "\0\u2244\0\u2288\0\u22cc\0\u2310\0\104\0\u2354\0\u2398\0\104"+ + "\0\u23dc\0\314\0\u2420\0\u2464\0\314\0\u24a8\0\314\0\314"+ + "\0\u24ec\0\u2530\0\u2574\0\u25b8\0\u25fc\0\u2640\0\314\0\u2684"+ + "\0\u26c8\0\u270c\0\u2750\0\u2794\0\u27d8\0\314\0\u281c\0\u2860"+ + "\0\u28a4\0\314\0\u28e8\0\314\0\u292c\0\u2970\0\u29b4\0\314"+ + "\0\u29f8\0\u2a3c\0\u2a80\0\u2ac4\0\u2b08\0\u2b4c\0\314\0\u2b90"+ + "\0\u2bd4\0\u2c18\0\u2c5c\0\u2ca0\0\314\0\u2ce4\0\104\0\u2d28"+ + "\0\u2d6c\0\u2db0\0\u2df4\0\u2e38\0\314\0\314\0\u2e7c\0\u2ec0"+ + "\0\u2f04\0\u2f48\0\u2f8c\0\314\0\u2fd0\0\314\0\u3014\0\u3058"+ + "\0\314\0\u309c\0\314\0\314\0\u30e0\0\314\0\u3124\0\u3168"+ + "\0\u31ac\0\u31f0\0\u3234\0\u3278\0\u32bc\0\u3300\0\u3344\0\u3388"+ + "\0\u33cc\0\314\0\u3410\0\314\0\314\0\u3454\0\u3498\0\314"+ + "\0\u34dc\0\u3520\0\314\0\u3564\0\314\0\314\0\u35a8\0\u35ec"+ + "\0\u3630\0\u3674\0\u36b8\0\314\0\u36fc\0\314\0\u3740\0\u3784"+ + "\0\314\0\u37c8\0\u380c\0\u3850\0\314\0\314\0\u3894\0\u38d8"+ + "\0\u391c\0\314\0\u3960\0\u39a4\0\u39e8\0\u3a2c\0\314\0\u3a70"+ + "\0\314\0\314\0\u3ab4\0\u3af8\0\314\0\314\0\u3b3c\0\314"+ + "\0\u3b80\0\u3bc4\0\u3c08\0\u3c4c\0\314\0\314\0\u3c90\0\314"+ + "\0\u3cd4\0\u3d18\0\314\0\u3d5c\0\314\0\314\0\u3da0\0\314"; private static int [] zzUnpackRowMap() { - int [] result = new int[342]; + int [] result = new int[320]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -274,379 +268,342 @@ class _JavaLexer implements FlexLexer { private static final String ZZ_TRANS_PACKED_0 = "\1\2\1\3\1\4\1\2\1\5\1\6\1\3\1\7"+ - "\1\4\1\7\1\4\1\7\1\10\5\4\1\11\1\4"+ - "\1\12\1\4\1\3\1\13\1\2\1\14\1\15\1\16"+ - "\1\4\1\17\1\20\1\21\1\22\1\23\1\24\1\25"+ - "\1\26\4\4\1\27\1\30\2\4\1\31\1\32\1\33"+ - "\1\34\1\4\1\35\1\36\1\37\1\40\1\41\1\42"+ - "\1\43\1\44\1\45\1\46\1\47\1\50\1\51\1\52"+ - "\1\53\1\54\1\55\1\56\1\57\1\60\1\61\110\0"+ - "\1\3\4\0\1\3\17\0\1\3\62\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\30\4\31\0"+ - "\1\62\1\63\54\0\1\64\106\0\1\65\33\0\1\7"+ - "\1\66\1\7\1\0\2\7\2\0\1\67\1\70\1\71"+ - "\1\72\1\73\11\0\1\73\1\70\1\0\1\67\11\0"+ - "\1\71\43\0\1\74\1\75\1\76\1\0\2\76\1\77"+ - "\1\100\1\67\1\70\1\71\1\72\1\73\11\0\1\73"+ - "\1\70\1\0\1\67\2\0\1\100\6\0\1\71\1\0"+ - "\1\77\41\0\1\101\1\0\1\101\1\0\2\101\5\0"+ - "\1\102\110\0\1\103\35\0\1\104\4\0\1\105\17\0"+ - "\6\13\1\0\17\13\1\0\1\106\1\107\56\13\6\14"+ - "\1\0\17\14\1\0\1\14\1\110\1\111\55\14\2\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\1\4\1\112\14\4\1\113\11\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\3\4\1\114"+ - "\24\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\6\4\1\115\1\4\1\116\11\4\1\117"+ - "\5\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\5\4\1\120\1\121\4\4\1\122\3\4"+ - "\1\123\10\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\7\4\1\124\1\4\1\125\16\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\13\4\1\126\14\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\1\127\1\4\1\130"+ - "\12\4\1\131\1\132\7\4\1\133\1\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\2\4"+ - "\1\134\1\135\1\4\1\136\22\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\1\4\1\137"+ - "\11\4\1\140\1\4\1\141\12\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\5\4\1\142"+ - "\1\143\4\4\1\144\2\4\1\145\11\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\4\4"+ - "\1\146\3\4\1\147\10\4\1\150\6\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\3\4"+ - "\1\151\7\4\1\152\14\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\13\4\1\153\14\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\1\4\1\154\1\155\2\4\1\156\22\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\13\4\1\157\14\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\16\4\1\160\11\4\107\0"+ - "\1\161\106\0\1\162\106\0\1\163\1\0\1\164\104\0"+ - "\1\165\2\0\1\166\103\0\1\167\3\0\1\170\102\0"+ - "\1\171\5\0\1\172\100\0\1\173\106\0\1\174\131\0"+ - "\1\175\1\0\6\62\1\0\17\62\1\0\60\62\5\176"+ - "\1\177\101\176\7\0\1\7\1\66\1\7\1\0\2\7"+ - "\101\0\1\101\1\0\1\101\1\0\2\101\3\0\1\70"+ - "\1\71\1\0\1\73\11\0\1\73\1\70\13\0\1\71"+ - "\43\0\1\200\1\0\1\200\1\0\2\200\3\0\1\70"+ - "\1\71\2\0\1\201\11\0\1\70\13\0\1\71\12\0"+ - "\1\201\30\0\1\74\1\202\1\74\1\0\2\74\3\0"+ - "\1\70\1\71\1\72\1\73\11\0\1\73\1\70\13\0"+ - "\1\71\43\0\1\74\1\75\1\76\1\0\2\76\101\0"+ - "\1\74\1\75\1\76\1\0\2\76\2\0\1\67\1\70"+ - "\1\71\1\72\1\73\11\0\1\73\1\70\1\0\1\67"+ - "\11\0\1\71\34\0\7\203\1\204\1\203\4\204\1\203"+ - "\1\204\1\205\2\204\1\203\1\204\1\203\1\206\1\0"+ - "\6\203\3\204\1\205\2\203\2\204\5\203\1\204\3\203"+ - "\1\206\30\203\13\0\2\207\2\0\1\67\20\0\1\67"+ - "\55\0\1\101\1\210\1\101\1\0\2\101\3\0\1\70"+ - "\1\71\1\0\1\73\11\0\1\73\1\70\13\0\1\71"+ - "\56\0\1\211\64\0\6\13\1\0\17\13\1\0\60\13"+ - "\6\14\1\0\17\14\1\0\60\14\2\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\2\4\1\212"+ - "\2\4\1\213\7\4\1\214\12\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\1\4\1\215"+ - "\15\4\1\216\10\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\1\217\27\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\7\4"+ - "\1\220\20\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\2\4\1\221\25\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\1\222"+ - "\27\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\6\4\1\223\21\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\13\4\1\224"+ - "\14\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\1\4\1\225\26\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\10\4\1\226"+ - "\17\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\7\4\1\227\20\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\7\4\1\230"+ - "\20\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\10\4\1\231\17\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\1\4\1\232"+ - "\3\4\1\233\22\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\24\4\1\234\3\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\10\4\1\235\17\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\13\4\1\236\14\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\17\4\1\237\10\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\6\4\1\240\21\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\26\4\1\241\1\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\1\242\27\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\3\4"+ - "\1\243\24\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\13\4\1\244\14\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\1\245"+ - "\27\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\1\246\6\4\1\247\20\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\5\4"+ - "\1\250\22\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\10\4\1\251\17\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\5\4"+ - "\1\252\22\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\1\253\6\4\1\254\20\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\24\4\1\255\3\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\4\4\1\256\23\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\2\4\1\257\25\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\1\260\27\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\13\4"+ - "\1\261\3\4\1\262\10\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\11\4\1\263\16\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\12\4\1\264\15\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\6\4\1\265\10\4"+ - "\1\266\10\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\17\4\1\267\10\4\107\0\1\270"+ - "\24\0\5\176\1\271\101\176\4\272\1\273\1\177\101\272"+ - "\7\0\1\200\1\274\1\200\1\0\2\200\3\0\1\70"+ - "\1\71\14\0\1\70\13\0\1\71\43\0\1\200\1\0"+ - "\1\200\1\0\2\200\3\0\1\70\1\71\14\0\1\70"+ - "\13\0\1\71\43\0\1\74\1\202\1\74\1\0\2\74"+ - "\101\0\1\275\1\0\4\275\1\0\1\275\1\0\2\275"+ - "\1\0\1\275\1\0\1\276\7\0\3\275\3\0\2\275"+ - "\5\0\1\275\3\0\1\276\30\0\7\203\1\204\1\277"+ - "\4\204\1\203\1\204\1\205\2\204\1\203\1\204\1\203"+ - "\1\206\1\0\6\203\3\204\1\205\2\203\2\204\5\203"+ - "\1\204\3\203\1\206\30\203\7\0\1\300\1\0\1\300"+ - "\1\275\2\300\1\0\1\275\1\0\2\275\1\0\1\275"+ - "\1\301\1\276\7\0\3\275\3\0\2\275\5\0\1\275"+ - "\3\0\1\276\6\0\1\301\31\0\1\302\2\0\2\207"+ - "\2\0\1\67\20\0\1\67\55\0\1\101\1\210\1\101"+ - "\1\0\2\101\74\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\3\4\1\303\24\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\10\4"+ - "\1\304\17\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\13\4\1\305\14\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\7\4"+ - "\1\306\20\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\2\4\1\307\25\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\3\4"+ - "\1\310\24\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\21\4\1\311\6\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\3\4"+ - "\1\312\24\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\7\4\1\313\20\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\5\4"+ - "\1\314\22\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\5\4\1\315\22\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\3\4"+ - "\1\316\24\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\1\317\27\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\23\4\1\320"+ - "\4\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\17\4\1\321\10\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\1\322\27\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\3\4\1\323\24\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\12\4\1\324\15\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\1\4\1\325\26\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\1\326\27\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\6\4\1\327\21\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\17\4\1\330\10\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\5\4\1\331\22\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\6\4\1\332\21\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\3\4\1\333\24\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\12\4\1\334\15\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\3\4\1\335\24\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\7\4\1\336\20\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\1\337\6\4\1\340\20\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\1\4\1\341\26\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\3\4\1\342\24\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\1\343\27\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\6\4\1\344\4\4\1\345\14\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\5\4\1\346"+ - "\22\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\11\4\1\347\16\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\13\4\1\350"+ - "\14\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\1\351\27\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\25\4\1\352\2\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\6\4\1\353\21\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\14\4\1\354\13\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\5\4\1\355\22\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\20\4\1\356\7\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\6\4\1\357\21\4\25\0\4\176\1\360\1\271"+ - "\101\176\5\272\1\361\101\272\7\0\1\200\1\274\1\200"+ - "\1\0\2\200\101\0\1\275\1\362\4\275\1\0\1\275"+ - "\1\0\2\275\1\0\1\275\1\0\1\276\7\0\3\275"+ - "\3\0\2\275\5\0\1\275\3\0\1\276\37\0\1\200"+ - "\1\0\1\200\1\0\2\200\7\0\1\301\40\0\1\301"+ - "\30\0\1\204\1\363\4\204\1\0\1\204\1\0\2\204"+ - "\1\0\1\204\1\0\1\276\7\0\3\204\3\0\2\204"+ - "\5\0\1\204\3\0\1\276\37\0\1\300\1\364\1\300"+ - "\1\275\2\300\1\0\1\275\1\0\1\365\1\366\1\0"+ - "\1\275\1\0\1\276\7\0\1\275\1\365\1\275\3\0"+ - "\2\275\5\0\1\366\3\0\1\276\37\0\1\200\1\0"+ - "\1\200\1\0\2\200\102\0\1\302\2\0\2\207\74\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\7\4\1\367\20\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\26\4\1\370\1\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\1\4\1\371\26\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\10\4\1\372\17\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\3\4\1\373\24\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\1\374\27\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\6\4"+ - "\1\375\21\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\1\4\1\376\26\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\1\4"+ - "\1\377\26\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\12\4\1\u0100\15\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\17\4"+ - "\1\u0101\10\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\1\4\1\u0102\26\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\16\4"+ - "\1\u0103\11\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\1\u0104\27\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\12\4\1\u0105"+ - "\15\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\25\4\1\u0106\2\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\14\4\1\u0107"+ - "\13\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\3\4\1\u0108\24\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\16\4\1\u0109"+ - "\11\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\7\4\1\u010a\20\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\17\4\1\u010b"+ - "\10\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\1\u010c\27\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\1\4\1\u010d\26\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\5\4\1\u010e\22\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\3\4\1\u010f\24\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\1\4\1\u0110\26\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\2\4\1\u0111\25\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\6\4\1\u0112\21\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\3\4\1\u0113\24\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\5\4\1\u0114\22\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\17\4\1\u0115\10\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\5\4\1\u0116\22\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\1\u0117\27\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\3\4\1\u0118\24\4\25\0\4\272\1\273\1\361\101\272"+ - "\7\0\1\275\1\362\4\275\1\0\1\275\1\0\2\275"+ - "\1\0\1\275\11\0\3\275\3\0\2\275\5\0\1\275"+ - "\43\0\1\204\1\363\4\204\1\0\1\204\1\0\2\204"+ - "\1\0\1\204\11\0\3\204\3\0\2\204\5\0\1\204"+ - "\43\0\1\300\1\364\1\300\1\275\2\300\1\0\1\275"+ - "\1\0\2\275\1\0\1\275\11\0\3\275\3\0\2\275"+ - "\5\0\1\275\36\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\17\4\1\u0119\10\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\7\4"+ - "\1\u011a\20\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\10\4\1\u011b\17\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\20\4"+ - "\1\u011c\7\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\6\4\1\u011d\21\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\1\u011e"+ - "\27\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\5\4\1\u011f\22\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\1\u0120\27\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\12\4\1\u0121\15\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\1\4\1\u0122\26\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\16\4\1\u0123\11\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\3\4\1\u0124\24\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\5\4\1\u0125\22\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\10\4\1\u0126\17\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\4\4\1\u0127\23\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\10\4\1\u0128\17\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\21\4\1\u0129\6\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\1\u012a\27\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\6\4\1\u012b\21\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\3\4\1\u012c\24\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\12\4\1\u012d\15\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\1\u012e\27\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\12\4"+ - "\1\u012f\15\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\23\4\1\u0130\4\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\17\4"+ - "\1\u0131\10\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\3\4\1\u0132\24\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\7\4"+ - "\1\u0133\20\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\15\4\1\u0134\12\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\12\4"+ - "\1\u0135\15\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\4\4\1\u0136\23\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\13\4"+ - "\1\u0137\14\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\10\4\1\u0138\17\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\2\4"+ - "\1\u0139\25\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\5\4\1\u013a\22\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\12\4"+ - "\1\u013b\15\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\3\4\1\u013c\24\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\1\u013d"+ - "\27\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\1\u013e\27\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\3\4\1\u013f\24\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\3\4\1\u0140\24\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\6\4\1\u0141\21\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\10\4\1\u0142\17\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\1\u0143\27\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\24\4\1\u0144\3\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\10\4\1\u0145\17\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\3\4\1\u0146\24\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\12\4\1\u0147\15\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\3\4\1\u0148\24\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\10\4\1\u0149\17\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\3\4\1\u014a\24\4\27\0\2\4\3\0\13\4\1\0"+ - "\1\4\1\0\1\4\4\0\3\4\1\u014b\24\4\27\0"+ - "\2\4\3\0\13\4\1\0\1\4\1\0\1\4\4\0"+ - "\1\u014c\27\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\17\4\1\u014d\10\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\3\4"+ - "\1\u014e\24\4\27\0\2\4\3\0\13\4\1\0\1\4"+ - "\1\0\1\4\4\0\13\4\1\u014f\14\4\27\0\2\4"+ - "\3\0\13\4\1\0\1\4\1\0\1\4\4\0\1\u0150"+ - "\27\4\27\0\2\4\3\0\13\4\1\0\1\4\1\0"+ - "\1\4\4\0\20\4\1\u0151\7\4\27\0\2\4\3\0"+ - "\13\4\1\0\1\4\1\0\1\4\4\0\27\4\1\u0152"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\4\4\1\u0153\23\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\7\4\1\u0154\20\4"+ - "\27\0\2\4\3\0\13\4\1\0\1\4\1\0\1\4"+ - "\4\0\3\4\1\u0155\24\4\27\0\2\4\3\0\13\4"+ - "\1\0\1\4\1\0\1\4\4\0\20\4\1\u0156\7\4"+ - "\25\0"; + "\3\4\1\10\4\4\1\11\1\4\1\12\1\4\1\13"+ + "\1\2\1\14\1\15\1\16\1\4\1\17\1\20\1\21"+ + "\1\22\1\23\1\24\1\25\1\26\4\4\1\27\1\30"+ + "\2\4\1\31\1\32\1\33\1\34\1\4\1\35\1\36"+ + "\1\37\1\40\1\41\1\42\1\43\1\44\1\45\1\46"+ + "\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56"+ + "\1\57\1\60\1\61\105\0\1\3\4\0\1\3\77\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\30\4\31\0\1\62\1\63\51\0\1\64\103\0\1\65"+ + "\33\0\2\7\1\0\1\66\1\7\2\0\1\67\1\70"+ + "\1\71\1\72\10\0\1\72\1\67\1\0\1\66\11\0"+ + "\1\70\43\0\2\7\1\0\1\66\1\7\1\73\1\74"+ + "\1\67\1\70\1\71\1\72\10\0\1\72\1\67\1\0"+ + "\1\66\2\0\1\74\6\0\1\70\1\0\1\73\41\0"+ + "\1\71\3\0\1\71\4\0\1\75\105\0\1\76\34\0"+ + "\1\77\4\0\1\100\17\0\6\13\1\0\15\13\1\101"+ + "\1\102\56\13\6\14\1\0\16\14\1\103\1\104\55\14"+ + "\2\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\1\4\1\105\14\4\1\106\11\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\3\4"+ + "\1\107\24\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\6\4\1\110\1\4\1\111\11\4"+ + "\1\112\5\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\5\4\1\113\1\114\4\4\1\115"+ + "\3\4\1\116\10\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\7\4\1\117\1\4\1\120"+ + "\16\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\13\4\1\121\14\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\1\122\1\4"+ + "\1\123\12\4\1\124\1\125\7\4\1\126\1\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\2\4\1\127\1\130\1\4\1\131\22\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\1\4"+ + "\1\132\11\4\1\133\1\4\1\134\12\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\5\4"+ + "\1\135\1\136\4\4\1\137\2\4\1\140\11\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\4\4\1\141\3\4\1\142\10\4\1\143\6\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\3\4\1\144\7\4\1\145\14\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\13\4\1\146"+ + "\14\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\1\4\1\147\1\150\2\4\1\151\22\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\13\4\1\152\14\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\16\4\1\153\11\4"+ + "\104\0\1\154\103\0\1\155\103\0\1\156\1\0\1\157"+ + "\101\0\1\160\2\0\1\161\100\0\1\162\3\0\1\163"+ + "\77\0\1\164\5\0\1\165\75\0\1\166\103\0\1\167"+ + "\126\0\1\170\1\0\6\62\1\0\75\62\5\171\1\172"+ + "\76\171\7\0\2\71\2\0\1\71\2\0\1\67\1\70"+ + "\1\0\1\72\10\0\1\72\1\67\13\0\1\70\43\0"+ + "\2\173\2\0\1\173\2\0\1\67\1\70\2\0\1\173"+ + "\10\0\1\67\13\0\1\70\12\0\1\173\30\0\3\174"+ + "\1\66\1\174\1\0\3\174\1\175\1\174\10\0\3\174"+ + "\1\66\2\0\2\174\5\0\1\174\43\0\2\74\1\0"+ + "\1\66\1\74\21\0\1\66\66\0\1\176\63\0\6\13"+ + "\1\0\75\13\6\14\1\0\75\14\2\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\2\4\1\177"+ + "\2\4\1\200\7\4\1\201\12\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\1\4\1\202"+ + "\15\4\1\203\10\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\1\204\27\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\7\4"+ + "\1\205\20\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\2\4\1\206\25\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\1\207"+ + "\27\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\6\4\1\210\21\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\13\4\1\211"+ + "\14\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\1\4\1\212\26\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\10\4\1\213"+ + "\17\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\7\4\1\214\20\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\7\4\1\215"+ + "\20\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\10\4\1\216\17\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\1\4\1\217"+ + "\3\4\1\220\22\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\24\4\1\221\3\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\10\4\1\222\17\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\13\4\1\223\14\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\17\4\1\224\10\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\6\4\1\225\21\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\26\4\1\226\1\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\1\227\27\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\3\4"+ + "\1\230\24\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\13\4\1\231\14\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\1\232"+ + "\27\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\1\233\6\4\1\234\20\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\5\4"+ + "\1\235\22\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\10\4\1\236\17\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\5\4"+ + "\1\237\22\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\1\240\6\4\1\241\20\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\24\4\1\242\3\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\4\4\1\243\23\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\2\4\1\244\25\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\1\245\27\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\13\4"+ + "\1\246\3\4\1\247\10\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\11\4\1\250\16\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\12\4\1\251\15\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\6\4\1\252\10\4"+ + "\1\253\10\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\17\4\1\254\10\4\104\0\1\255"+ + "\24\0\5\171\1\256\76\171\4\257\1\260\1\172\76\257"+ + "\7\0\2\173\2\0\1\173\2\0\1\67\1\70\13\0"+ + "\1\67\13\0\1\70\43\0\3\174\1\66\1\174\1\0"+ + "\3\174\1\261\1\174\1\0\1\72\6\0\3\174\1\66"+ + "\2\0\2\174\5\0\1\174\3\0\1\72\37\0\3\261"+ + "\1\0\1\261\1\0\3\261\1\0\1\261\10\0\3\261"+ + "\3\0\2\261\5\0\1\261\36\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\3\4\1\262\24\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\10\4\1\263\17\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\13\4\1\264\14\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\7\4\1\265\20\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\2\4\1\266\25\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\3\4\1\267\24\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\21\4\1\270\6\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\3\4\1\271\24\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\7\4\1\272\20\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\5\4\1\273\22\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\5\4\1\274\22\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\3\4\1\275\24\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\1\276\27\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\23\4\1\277\4\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\17\4\1\300\10\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\1\301\27\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\3\4\1\302\24\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\12\4"+ + "\1\303\15\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\1\4\1\304\26\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\1\305"+ + "\27\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\6\4\1\306\21\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\17\4\1\307"+ + "\10\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\5\4\1\310\22\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\6\4\1\311"+ + "\21\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\3\4\1\312\24\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\12\4\1\313"+ + "\15\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\3\4\1\314\24\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\7\4\1\315"+ + "\20\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\1\316\6\4\1\317\20\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\1\4"+ + "\1\320\26\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\3\4\1\321\24\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\1\322"+ + "\27\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\6\4\1\323\4\4\1\324\14\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\5\4\1\325\22\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\11\4\1\326\16\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\13\4\1\327\14\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\1\330\27\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\25\4"+ + "\1\331\2\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\6\4\1\332\21\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\14\4"+ + "\1\333\13\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\5\4\1\334\22\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\20\4"+ + "\1\335\7\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\6\4\1\336\21\4\25\0\4\171"+ + "\1\337\1\256\76\171\5\257\1\340\76\257\7\0\3\261"+ + "\1\0\1\261\1\0\3\261\1\0\1\261\1\0\1\72"+ + "\6\0\3\261\3\0\2\261\5\0\1\261\3\0\1\72"+ + "\32\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\7\4\1\341\20\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\26\4\1\342\1\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\1\4\1\343\26\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\10\4\1\344\17\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\3\4\1\345\24\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\1\346\27\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\6\4\1\347\21\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\1\4\1\350\26\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\1\4\1\351\26\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\12\4\1\352\15\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\17\4\1\353\10\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\1\4\1\354\26\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\16\4\1\355\11\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\1\356\27\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\12\4"+ + "\1\357\15\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\25\4\1\360\2\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\14\4"+ + "\1\361\13\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\3\4\1\362\24\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\16\4"+ + "\1\363\11\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\7\4\1\364\20\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\17\4"+ + "\1\365\10\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\1\366\27\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\1\4\1\367"+ + "\26\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\5\4\1\370\22\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\3\4\1\371"+ + "\24\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\1\4\1\372\26\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\2\4\1\373"+ + "\25\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\6\4\1\374\21\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\3\4\1\375"+ + "\24\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\5\4\1\376\22\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\17\4\1\377"+ + "\10\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\5\4\1\u0100\22\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\1\u0101\27\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\3\4\1\u0102\24\4\25\0\4\257\1\260\1\340"+ + "\76\257\2\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\17\4\1\u0103\10\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\7\4\1\u0104"+ + "\20\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\10\4\1\u0105\17\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\20\4\1\u0106"+ + "\7\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\6\4\1\u0107\21\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\1\u0108\27\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\5\4\1\u0109\22\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\1\u010a\27\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\12\4\1\u010b\15\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\1\4\1\u010c\26\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\16\4\1\u010d\11\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\3\4\1\u010e\24\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\5\4\1\u010f\22\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\10\4\1\u0110\17\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\4\4\1\u0111\23\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\10\4\1\u0112\17\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\21\4\1\u0113\6\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\1\u0114\27\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\6\4"+ + "\1\u0115\21\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\3\4\1\u0116\24\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\12\4"+ + "\1\u0117\15\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\1\u0118\27\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\12\4\1\u0119"+ + "\15\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\23\4\1\u011a\4\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\17\4\1\u011b"+ + "\10\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\3\4\1\u011c\24\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\7\4\1\u011d"+ + "\20\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\15\4\1\u011e\12\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\12\4\1\u011f"+ + "\15\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\4\4\1\u0120\23\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\13\4\1\u0121"+ + "\14\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\10\4\1\u0122\17\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\2\4\1\u0123"+ + "\25\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\5\4\1\u0124\22\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\12\4\1\u0125"+ + "\15\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\3\4\1\u0126\24\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\1\u0127\27\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\1\u0128\27\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\3\4\1\u0129\24\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\3\4\1\u012a\24\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\6\4\1\u012b\21\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\10\4\1\u012c\17\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\1\u012d\27\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\24\4"+ + "\1\u012e\3\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\10\4\1\u012f\17\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\3\4"+ + "\1\u0130\24\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\12\4\1\u0131\15\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\3\4"+ + "\1\u0132\24\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\10\4\1\u0133\17\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\3\4"+ + "\1\u0134\24\4\27\0\2\4\3\0\11\4\1\0\1\4"+ + "\1\0\1\4\3\0\3\4\1\u0135\24\4\27\0\2\4"+ + "\3\0\11\4\1\0\1\4\1\0\1\4\3\0\1\u0136"+ + "\27\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\17\4\1\u0137\10\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\3\4\1\u0138"+ + "\24\4\27\0\2\4\3\0\11\4\1\0\1\4\1\0"+ + "\1\4\3\0\13\4\1\u0139\14\4\27\0\2\4\3\0"+ + "\11\4\1\0\1\4\1\0\1\4\3\0\1\u013a\27\4"+ + "\27\0\2\4\3\0\11\4\1\0\1\4\1\0\1\4"+ + "\3\0\20\4\1\u013b\7\4\27\0\2\4\3\0\11\4"+ + "\1\0\1\4\1\0\1\4\3\0\27\4\1\u013c\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\4\4\1\u013d\23\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\7\4\1\u013e\20\4\27\0"+ + "\2\4\3\0\11\4\1\0\1\4\1\0\1\4\3\0"+ + "\3\4\1\u013f\24\4\27\0\2\4\3\0\11\4\1\0"+ + "\1\4\1\0\1\4\3\0\20\4\1\u0140\7\4\25\0"; private static int [] zzUnpackTrans() { - int [] result = new int[17892]; + int [] result = new int[15844]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -688,14 +645,12 @@ class _JavaLexer implements FlexLexer { private static final String ZZ_ATTRIBUTE_PACKED_0 = "\1\0\1\11\37\1\1\11\3\1\12\11\1\1\1\11"+ - "\2\1\2\11\1\0\3\11\2\1\2\0\4\1\1\0"+ - "\4\11\2\1\1\11\47\1\7\11\1\1\5\11\4\1"+ - "\2\0\2\1\1\0\1\1\1\0\1\11\56\1\1\11"+ - "\1\0\1\1\1\11\4\0\1\1\2\0\55\1\1\11"+ - "\4\0\142\1"; + "\2\1\5\11\4\1\1\0\4\11\2\1\1\11\47\1"+ + "\7\11\1\1\5\11\4\1\1\0\1\11\56\1\1\11"+ + "\1\0\1\1\1\11\1\0\55\1\1\11\1\0\140\1"; private static int [] zzUnpackAttribute() { - int [] result = new int[342]; + int [] result = new int[320]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -794,7 +749,7 @@ class _JavaLexer implements FlexLexer { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ - while (i < 1788) { + while (i < 1784) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); @@ -975,7 +930,7 @@ class _JavaLexer implements FlexLexer { while (true) { if (zzCurrentPosL < zzEndReadL) - zzInput = zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++]:zzBufferL.charAt(zzCurrentPosL++); + zzInput = (zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++] : zzBufferL.charAt(zzCurrentPosL++)); else if (zzAtEOF) { zzInput = YYEOF; break zzForAction; @@ -995,7 +950,7 @@ class _JavaLexer implements FlexLexer { break zzForAction; } else { - zzInput = zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++]:zzBufferL.charAt(zzCurrentPosL++); + zzInput = (zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++] : zzBufferL.charAt(zzCurrentPosL++)); } } int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java index 07195ba43c32..c16225be5c00 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java @@ -20,6 +20,7 @@ import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.roots.PackageIndex; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; @@ -359,9 +360,15 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx { @Override public Set<String> getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) { Set<String> names = null; + FileIndexFacade facade = FileIndexFacade.getInstance(myProject); for (PsiDirectory dir : psiPackage.getDirectories(scope)) { for (PsiFile file : dir.getFiles()) { if (file instanceof PsiClassOwner && file.getViewProvider().getLanguages().size() == 1) { + VirtualFile vFile = file.getVirtualFile(); + if (vFile != null && !facade.isInSourceContent(vFile) && !(file instanceof PsiCompiledElement)) { + continue; + } + Set<String> inFile = file instanceof PsiClassOwnerEx ? ((PsiClassOwnerEx)file).getClassNames() : getClassNames(((PsiClassOwner)file).getClasses()); if (inFile.isEmpty()) continue; @@ -377,7 +384,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx { @Override public boolean processPackageDirectories(@NotNull PsiPackage psiPackage, @NotNull final GlobalSearchScope scope, @NotNull final Processor<PsiDirectory> consumer) { final PsiManager psiManager = PsiManager.getInstance(getProject()); - PackageIndex.getInstance(getProject()).getDirsByPackageName(psiPackage.getQualifiedName(), false).forEach(new ReadActionProcessor<VirtualFile>() { + return PackageIndex.getInstance(getProject()).getDirsByPackageName(psiPackage.getQualifiedName(), false).forEach(new ReadActionProcessor<VirtualFile>() { @Override public boolean processInReadAction(final VirtualFile dir) { if (!scope.contains(dir)) return true; @@ -385,7 +392,6 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx { return psiDir == null || consumer.process(psiDir); } }); - return true; } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiNameHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiNameHelperImpl.java index 1be15ef94706..c08d2dafec3d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiNameHelperImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiNameHelperImpl.java @@ -33,7 +33,11 @@ public class PsiNameHelperImpl extends PsiNameHelper { @Override public boolean isIdentifier(@Nullable String text) { - return isIdentifier(text, myLanguageLevelExtension.getLanguageLevel()); + return isIdentifier(text, getLanguageLevel()); + } + + protected LanguageLevel getLanguageLevel() { + return myLanguageLevelExtension.getLanguageLevel(); } @Override @@ -43,7 +47,7 @@ public class PsiNameHelperImpl extends PsiNameHelper { @Override public boolean isKeyword(@Nullable String text) { - return text != null && JavaLexer.isKeyword(text, myLanguageLevelExtension.getLanguageLevel()); + return text != null && JavaLexer.isKeyword(text, getLanguageLevel()); } @Override @@ -58,4 +62,17 @@ public class PsiNameHelperImpl extends PsiNameHelper { index = index1 + 1; } } + + public static PsiNameHelper getInstance() { + return new PsiNameHelperImpl() { + @Override + protected LanguageLevel getLanguageLevel() { + return LanguageLevel.HIGHEST; + } + }; + } + + private PsiNameHelperImpl() { + myLanguageLevelExtension = null; + } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java index 8912db121125..4c23edadaba3 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java @@ -277,8 +277,8 @@ public class PsiSuperMethodImplUtil { } if (containingClass != null) { - if (!containingClass.isInterface()) { - return true; + if (containingClass.isInterface()) { + return false; } if (!aClass.isInterface() && !InheritanceUtil.isInheritorOrSelf(superClass, containingClass, true)) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java index 7963ed77edfe..118af69cee72 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java @@ -39,7 +39,7 @@ public class ClassFileStubBuilder implements BinaryFileStubBuilder { final ClsStubBuilderFactory[] factories = Extensions.getExtensions(ClsStubBuilderFactory.EP_NAME); for (ClsStubBuilderFactory factory : factories) { if (!factory.isInnerClass(file) && factory.canBeProcessed(file, content)) { - PsiFileStub stub = factory.buildFileStub(file, content); + PsiFileStub stub = factory.buildFileStub(file, content, project); if (stub != null) return stub; } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java index 129b441e761c..553a5feb38c0 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java @@ -40,7 +40,7 @@ import javax.swing.*; public class ClsParameterImpl extends ClsRepositoryPsiElement<PsiParameterStub> implements PsiParameter { private PsiTypeElement myType = null; private String myName; - private String myMirrorName = null; + private volatile String myMirrorName = null; public ClsParameterImpl(@NotNull PsiParameterStub stub) { super(stub); @@ -142,43 +142,52 @@ public class ClsParameterImpl extends ClsRepositoryPsiElement<PsiParameterStub> } private String getMirrorName() { - synchronized (LAZY_BUILT_LOCK) { - if (myMirrorName == null) { - @NonNls String name; - - final PsiParameterStubImpl stub = (PsiParameterStubImpl)getStub(); - if (!stub.isAutoGeneratedName() || DumbService.getInstance(getProject()).isDumb()) { - name = stub.getName(); + String mirrorName = myMirrorName; + if (mirrorName == null) { + // avoid calculation of nice parameter name under lock as we might need indices for coolness + // and latter might produce deadlock, see IDEA-99248 + mirrorName = calcNiceParameterName(); + synchronized (LAZY_BUILT_LOCK) { + if (myMirrorName == null) { + myMirrorName = mirrorName; } - else { - JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(getProject()); - String[] nameSuggestions = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, getType()).names; + } + } + return mirrorName; + } - name = "p"; - if (nameSuggestions.length > 0) { - name = nameSuggestions[0]; - } + private String calcNiceParameterName() { + @NonNls String name; - PsiParameter[] parameters = ((PsiParameterList) getParent()).getParameters(); - AttemptsLoop: - while (true) { - for (PsiParameter parameter : parameters) { - if (parameter == this) break AttemptsLoop; - String name1 = ((ClsParameterImpl) parameter).getMirrorName(); - if (name.equals(name1)) { - name = nextName(name); - continue AttemptsLoop; - } - } - } - } + final PsiParameterStubImpl stub = (PsiParameterStubImpl)getStub(); + if (!stub.isAutoGeneratedName() || DumbService.getInstance(getProject()).isDumb()) { + name = stub.getName(); + } + else { + JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(getProject()); + String[] nameSuggestions = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, getType()).names; - assert name != null : stub; - myMirrorName = name; + name = "p"; + if (nameSuggestions.length > 0) { + name = nameSuggestions[0]; } - return myMirrorName; + PsiParameter[] parameters = ((PsiParameterList) getParent()).getParameters(); + AttemptsLoop: + while (true) { + for (PsiParameter parameter : parameters) { + if (parameter == this) break AttemptsLoop; + String name1 = ((ClsParameterImpl) parameter).getMirrorName(); + if (name.equals(name1)) { + name = nextName(name); + continue AttemptsLoop; + } + } + } } + + assert name != null : stub; + return name; } private static String nextName(String name) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsStubBuilderFactory.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsStubBuilderFactory.java index 8da85a67644d..49cdf57e379d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsStubBuilderFactory.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsStubBuilderFactory.java @@ -16,6 +16,7 @@ package com.intellij.psi.impl.compiled; import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.stubs.PsiFileStub; @@ -32,6 +33,11 @@ public abstract class ClsStubBuilderFactory<T extends PsiFile> { @Nullable public abstract PsiFileStub<T> buildFileStub(final VirtualFile file, byte[] bytes) throws ClsFormatException; + @Nullable + public PsiFileStub<T> buildFileStub(final VirtualFile file, byte[] bytes, Project project) throws ClsFormatException { + return buildFileStub(file, bytes); + } + public abstract boolean canBeProcessed(final VirtualFile file, byte[] bytes); /** diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java index 40c50a568557..ce1de29dbb67 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -47,8 +47,6 @@ import java.io.IOException; * @author max */ public abstract class JavaClassElementType extends JavaStubElementType<PsiClassStub, PsiClass> { - public static boolean DEBUG = false; - public JavaClassElementType(@NotNull @NonNls final String id) { super(id); } @@ -185,11 +183,6 @@ public abstract class JavaClassElementType extends JavaStubElementType<PsiClassS @Override public void indexStub(final PsiClassStub stub, final IndexSink sink) { - if (DEBUG) { - System.out.println("JavaClassElementType.indexStub"); - System.out.println("stub.getName() = " + stub.getName()); - } - boolean isAnonymous = stub.isAnonymous(); if (isAnonymous) { String baseRef = stub.getBaseClassReferenceText(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java index 8b2f16b6a8b4..f94bd2a132a9 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassImpl.java @@ -67,10 +67,18 @@ public class PsiClassImpl extends JavaStubPsiElement<PsiClassStub<?>> implements protected PsiClassImpl(final PsiClassStub stub, final IStubElementType type) { super(stub, type); + addTrace(); } public PsiClassImpl(final ASTNode node) { super(node); + addTrace(); + } + + private void addTrace() { + if (ourTraceStubAstBinding) { + putUserData(CREATION_TRACE, Thread.currentThread() + "\n" + DebugUtil.currentStackTrace()); + } } @Override diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java index f49b64e8d211..100529c55577 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.intellij.psi.impl.source; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; @@ -30,16 +31,19 @@ import com.intellij.psi.impl.DebugUtil; import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.PsiManagerEx; import com.intellij.psi.impl.source.resolve.ClassResolverProcessor; +import com.intellij.psi.impl.source.resolve.JavaResolveUtil; import com.intellij.psi.impl.source.resolve.ResolveCache; import com.intellij.psi.impl.source.resolve.VariableResolverProcessor; import com.intellij.psi.impl.source.tree.*; import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.scope.ElementClassFilter; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.scope.processor.FilterScopeProcessor; import com.intellij.psi.scope.util.PsiScopesUtil; import com.intellij.psi.tree.ChildRoleBase; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -59,17 +63,17 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme public static final int CLASS_FQ_OR_PACKAGE_NAME_KIND = 5; public static final int CLASS_IN_QUALIFIED_NEW_KIND = 6; - private final int myHC = CompositePsiElement.ourHC++; + @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod") private final int myHC = ourHC++; + + public PsiJavaCodeReferenceElementImpl() { + super(JavaElementType.JAVA_CODE_REFERENCE); + } @Override public final int hashCode() { return myHC; } - public PsiJavaCodeReferenceElementImpl() { - super(JavaElementType.JAVA_CODE_REFERENCE); - } - @Override public int getTextOffset() { final ASTNode refName = getReferenceNameNode(); @@ -128,36 +132,22 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme return PACKAGE_NAME_KIND; } if (i == JavaElementType.IMPORT_STATEMENT) { - final boolean isOnDemand = ((PsiImportStatement)SourceTreeToPsiMap.treeElementToPsi(treeParent)).isOnDemand(); + boolean isOnDemand = SourceTreeToPsiMap.<PsiImportStatement>treeToPsiNotNull(treeParent).isOnDemand(); return isOnDemand ? CLASS_FQ_OR_PACKAGE_NAME_KIND : CLASS_FQ_NAME_KIND; } if (i == JavaElementType.IMPORT_STATIC_STATEMENT) { return CLASS_FQ_OR_PACKAGE_NAME_KIND; } if (i == JavaElementType.JAVA_CODE_REFERENCE) { - final int parentKind = ((PsiJavaCodeReferenceElementImpl)treeParent).getKind(); - switch (parentKind) { - case CLASS_NAME_KIND: - return CLASS_OR_PACKAGE_NAME_KIND; - - case PACKAGE_NAME_KIND: - return PACKAGE_NAME_KIND; - - case CLASS_OR_PACKAGE_NAME_KIND: - return CLASS_OR_PACKAGE_NAME_KIND; - - case CLASS_FQ_NAME_KIND: - return CLASS_FQ_OR_PACKAGE_NAME_KIND; - - case CLASS_FQ_OR_PACKAGE_NAME_KIND: - return CLASS_FQ_OR_PACKAGE_NAME_KIND; - - case CLASS_IN_QUALIFIED_NEW_KIND: - return CLASS_IN_QUALIFIED_NEW_KIND; //?? - - default: - LOG.assertTrue(false); - return -1; + int parentKind = ((PsiJavaCodeReferenceElementImpl)treeParent).getKind(); + if (parentKind == CLASS_NAME_KIND) { + return CLASS_OR_PACKAGE_NAME_KIND; + } + else if (parentKind == CLASS_FQ_NAME_KIND) { + return CLASS_FQ_OR_PACKAGE_NAME_KIND; + } + else { + return parentKind; } } if (i == JavaElementType.CLASS || i == JavaElementType.PARAMETER_LIST || i == TokenType.ERROR_ELEMENT) { @@ -170,6 +160,11 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme i == JavaDocElementType.DOC_INLINE_TAG || i == JavaDocElementType.DOC_REFERENCE_HOLDER || i == JavaDocElementType.DOC_TYPE_HOLDER) { + PsiDocComment docComment = PsiTreeUtil.getParentOfType(this, PsiDocComment.class); + if (docComment != null && docComment.getOwner() == null && docComment.getParent() instanceof PsiJavaFile) { + return CLASS_FQ_OR_PACKAGE_NAME_KIND; + } + return CLASS_OR_PACKAGE_NAME_KIND; } if (isCodeFragmentType(i)) { @@ -202,9 +197,8 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme @Override public void deleteChildInternal(@NotNull final ASTNode child) { if (getChildRole(child) == ChildRole.QUALIFIER) { - final ASTNode dot = findChildByRole(ChildRole.DOT); - /*super.deleteChildInternal(child); - deleteChildInternal(dot);*/ + ASTNode dot = findChildByRole(ChildRole.DOT); + assert dot != null : this; deleteChildRange(child.getPsi(), dot.getPsi()); } else { @@ -343,36 +337,24 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme private static final class OurGenericsResolver implements ResolveCache.PolyVariantResolver<PsiJavaReference> { private static final OurGenericsResolver INSTANCE = new OurGenericsResolver(); - public static JavaResolveResult[] _resolve(final PsiJavaReference ref, final boolean incompleteCode) { - final PsiJavaCodeReferenceElementImpl referenceElement = (PsiJavaCodeReferenceElementImpl)ref; - final int kind = referenceElement.getKind(); + @NotNull + @Override + public JavaResolveResult[] resolve(@NotNull PsiJavaReference ref, boolean incompleteCode) { + PsiJavaCodeReferenceElementImpl referenceElement = (PsiJavaCodeReferenceElementImpl)ref; + int kind = referenceElement.getKind(); JavaResolveResult[] result = referenceElement.resolve(kind); + if (incompleteCode && result.length == 0 && kind != CLASS_FQ_NAME_KIND && kind != CLASS_FQ_OR_PACKAGE_NAME_KIND) { - final VariableResolverProcessor processor = new VariableResolverProcessor(referenceElement); + VariableResolverProcessor processor = new VariableResolverProcessor(referenceElement); PsiScopesUtil.resolveAndWalk(processor, referenceElement, null, incompleteCode); result = processor.getResult(); if (result.length == 0 && kind == CLASS_NAME_KIND) { - return referenceElement.resolve(PACKAGE_NAME_KIND); + result = referenceElement.resolve(PACKAGE_NAME_KIND); } } - return result; - } - @NotNull - @Override - public JavaResolveResult[] resolve(@NotNull final PsiJavaReference ref, final boolean incompleteCode) { - final JavaResolveResult[] result = _resolve(ref, incompleteCode); - if (result.length > 0 && result[0].getElement() instanceof PsiClass) { - final PsiType[] parameters = ((PsiJavaCodeReferenceElement)ref).getTypeParameters(); - final JavaResolveResult[] newResult = new JavaResolveResult[result.length]; - for (int i = 0; i < result.length; i++) { - final CandidateInfo resolveResult = (CandidateInfo)result[i]; - final PsiClass aClass = (PsiClass)resolveResult.getElement(); - assert aClass != null; - newResult[i] = !aClass.hasTypeParameters() ? resolveResult : new CandidateInfo(resolveResult, resolveResult.getSubstitutor().putAll(aClass, parameters)); - } - return newResult; - } + JavaResolveUtil.substituteResults((PsiJavaCodeReferenceElement)ref, result); + return result; } } @@ -381,8 +363,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme @NotNull public JavaResolveResult advancedResolve(final boolean incompleteCode) { final JavaResolveResult[] results = multiResolve(incompleteCode); - if (results.length == 1) return results[0]; - return JavaResolveResult.EMPTY; + return results.length == 1 ? results[0] : JavaResolveResult.EMPTY; } @Override @@ -409,15 +390,24 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme private JavaResolveResult[] resolve(final int kind) { switch (kind) { - case CLASS_FQ_NAME_KIND: + case CLASS_FQ_NAME_KIND: { // TODO: support type parameters in FQ names - final String textSkipWhiteSpaceAndComments = getTextSkipWhiteSpaceAndComments(); - if (textSkipWhiteSpaceAndComments == null || textSkipWhiteSpaceAndComments.length() == 0) return JavaResolveResult.EMPTY_ARRAY; - final PsiClass aClass = - JavaPsiFacade.getInstance(getProject()).findClass(textSkipWhiteSpaceAndComments, getResolveScope()); + String text = getTextSkipWhiteSpaceAndComments(); + if (StringUtil.isEmptyOrSpaces(text)) return JavaResolveResult.EMPTY_ARRAY; + + PsiClass aClass = JavaPsiFacade.getInstance(getProject()).findClass(text, getResolveScope()); if (aClass == null) return JavaResolveResult.EMPTY_ARRAY; - return new JavaResolveResult[]{new CandidateInfo(aClass, updateSubstitutor(PsiSubstitutor.EMPTY, aClass), this, false)}; + if (!isQualified() && text.equals(aClass.getQualifiedName())) { + PsiFile file = getContainingFile(); + if (file instanceof PsiJavaFile && !((PsiJavaFile)file).getPackageName().isEmpty()) { + // classes in default (unnamed) package cannot be referenced from other packages + return JavaResolveResult.EMPTY_ARRAY; + } + } + + return new JavaResolveResult[]{new CandidateInfo(aClass, updateSubstitutor(PsiSubstitutor.EMPTY, aClass), this, false)}; + } case CLASS_IN_QUALIFIED_NEW_KIND: { PsiElement parent = getParent(); if (parent instanceof JavaDummyHolder) { @@ -444,56 +434,54 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme if (qualifierType == null) return JavaResolveResult.EMPTY_ARRAY; if (!(qualifierType instanceof PsiClassType)) return JavaResolveResult.EMPTY_ARRAY; final JavaResolveResult result = PsiUtil.resolveGenericsClassInType(qualifierType); - if (result.getElement() == null) return JavaResolveResult.EMPTY_ARRAY; + final PsiElement resultElement = result.getElement(); + if (resultElement == null) return JavaResolveResult.EMPTY_ARRAY; final PsiElement classNameElement = getReferenceNameElement(); if (!(classNameElement instanceof PsiIdentifier)) return JavaResolveResult.EMPTY_ARRAY; final String className = classNameElement.getText(); final ClassResolverProcessor processor = new ClassResolverProcessor(className, this); - result.getElement().processDeclarations(processor, ResolveState.initial().put(PsiSubstitutor.KEY, result.getSubstitutor()), this, this); + resultElement.processDeclarations(processor, ResolveState.initial().put(PsiSubstitutor.KEY, result.getSubstitutor()), this, this); return processor.getResult(); } case CLASS_NAME_KIND: { final PsiElement classNameElement = getReferenceNameElement(); if (!(classNameElement instanceof PsiIdentifier)) return JavaResolveResult.EMPTY_ARRAY; final String className = classNameElement.getText(); - final ClassResolverProcessor processor = new ClassResolverProcessor(className, this); PsiScopesUtil.resolveAndWalk(processor, this, null); - return processor.getResult(); } - - case PACKAGE_NAME_KIND: - final String packageName = getTextSkipWhiteSpaceAndComments(); - final PsiManager manager = getManager(); - final PsiPackage aPackage = JavaPsiFacade.getInstance(manager.getProject()).findPackage(packageName); + case PACKAGE_NAME_KIND: { + String packageName = getTextSkipWhiteSpaceAndComments(); + Project project = getManager().getProject(); + PsiPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(packageName); if (aPackage == null || !aPackage.isValid()) { - return JavaPsiFacade.getInstance(manager.getProject()).isPartOfPackagePrefix(packageName) - ? CandidateInfo.RESOLVE_RESULT_FOR_PACKAGE_PREFIX_PACKAGE - : JavaResolveResult.EMPTY_ARRAY; + return JavaPsiFacade.getInstance(project).isPartOfPackagePrefix(packageName) ? + CandidateInfo.RESOLVE_RESULT_FOR_PACKAGE_PREFIX_PACKAGE : JavaResolveResult.EMPTY_ARRAY; } return new JavaResolveResult[]{new CandidateInfo(aPackage, PsiSubstitutor.EMPTY)}; - - case CLASS_FQ_OR_PACKAGE_NAME_KIND: { - final JavaResolveResult[] result = resolve(CLASS_FQ_NAME_KIND); - if (result.length == 0) { - return resolve(PACKAGE_NAME_KIND); + } + case CLASS_FQ_OR_PACKAGE_NAME_KIND: + case CLASS_OR_PACKAGE_NAME_KIND: { + int classKind = kind == CLASS_OR_PACKAGE_NAME_KIND ? CLASS_NAME_KIND : CLASS_FQ_NAME_KIND; + JavaResolveResult[] result = resolve(classKind); + + if (result.length == 1 && !result[0].isAccessible()) { + JavaResolveResult[] packageResult = resolve(PACKAGE_NAME_KIND); + if (packageResult.length != 0) { + result = packageResult; + } + } + else if (result.length == 0) { + result = resolve(PACKAGE_NAME_KIND); } + return result; } - case CLASS_OR_PACKAGE_NAME_KIND: - final JavaResolveResult[] classResolveResult = resolve(CLASS_NAME_KIND); - // [dsl]todo[ik]: review this change I guess ResolveInfo should be merged if both - // class and package resolve failed. - if (classResolveResult.length == 0) { - final JavaResolveResult[] packageResolveResult = resolve(PACKAGE_NAME_KIND); - if (packageResolveResult.length > 0) return packageResolveResult; - } - return classResolveResult; - default: - LOG.assertTrue(false); } + + LOG.assertTrue(false, this); return JavaResolveResult.EMPTY_ARRAY; } @@ -508,7 +496,6 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme return this; } - @Override public PsiElement bindToElement(@NotNull final PsiElement element) throws IncorrectOperationException { CheckUtil.checkWritable(this); @@ -615,10 +602,10 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme if (qualifier == null) return false; LOG.assertTrue(qualifier.getElementType() == JavaElementType.JAVA_CODE_REFERENCE); - final PsiElement refElement = ((PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(qualifier)).resolve(); + final PsiElement refElement = SourceTreeToPsiMap.<PsiJavaCodeReferenceElement>treeToPsiNotNull(qualifier).resolve(); if (refElement instanceof PsiPackage) return true; - return ((PsiJavaCodeReferenceElementImpl)SourceTreeToPsiMap.treeElementToPsi(qualifier)).isFullyQualified(); + return SourceTreeToPsiMap.<PsiJavaCodeReferenceElementImpl>treeToPsiNotNull(qualifier).isFullyQualified(); } private PsiElement bindToPackage(final PsiPackage aPackage) throws IncorrectOperationException { @@ -784,47 +771,42 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme filter.addFilter(ElementClassFilter.VARIABLE); } switch (getKind()) { - case CLASS_OR_PACKAGE_NAME_KIND: - addClassFilter(filter); - filter.addFilter(ElementClassFilter.PACKAGE_FILTER); - break; - case CLASS_NAME_KIND: - addClassFilter(filter); - if (isQualified()) { + case CLASS_OR_PACKAGE_NAME_KIND: + addClassFilter(filter); filter.addFilter(ElementClassFilter.PACKAGE_FILTER); - } - break; - case PACKAGE_NAME_KIND: - filter.addFilter(ElementClassFilter.PACKAGE_FILTER); - break; - case CLASS_FQ_NAME_KIND: - case CLASS_FQ_OR_PACKAGE_NAME_KIND: - filter.addFilter(ElementClassFilter.PACKAGE_FILTER); - if (isQualified()) { - filter.addFilter(ElementClassFilter.CLASS); - } - break; - case CLASS_IN_QUALIFIED_NEW_KIND: - final PsiElement parent = getParent(); - if (parent instanceof PsiNewExpression) { - final PsiNewExpression newExpr = (PsiNewExpression)parent; - final PsiType type = newExpr.getQualifier().getType(); - final PsiClass aClass = PsiUtil.resolveClassInType(type); - if (aClass != null) { - aClass.processDeclarations(new FilterScopeProcessor(new AndFilter(ElementClassFilter.CLASS, new ModifierFilter(PsiModifier.STATIC, false)), - processor), ResolveState.initial(), null, this); - } - // else{ - // throw new RuntimeException("Qualified new is not allowed for primitives"); - // } - } - // else{ - // throw new RuntimeException("Reference type is qualified new, but parent expression is: " + getParent()); - // } - - return; - default: - throw new RuntimeException("Unknown reference type"); + break; + case CLASS_NAME_KIND: + addClassFilter(filter); + if (isQualified()) { + filter.addFilter(ElementClassFilter.PACKAGE_FILTER); + } + break; + case PACKAGE_NAME_KIND: + filter.addFilter(ElementClassFilter.PACKAGE_FILTER); + break; + case CLASS_FQ_NAME_KIND: + case CLASS_FQ_OR_PACKAGE_NAME_KIND: + filter.addFilter(ElementClassFilter.PACKAGE_FILTER); + if (isQualified()) { + filter.addFilter(ElementClassFilter.CLASS); + } + break; + case CLASS_IN_QUALIFIED_NEW_KIND: + final PsiElement parent = getParent(); + if (parent instanceof PsiNewExpression) { + PsiExpression qualifier = ((PsiNewExpression)parent).getQualifier(); + assert qualifier != null : parent; + PsiType type = qualifier.getType(); + PsiClass aClass = PsiUtil.resolveClassInType(type); + if (aClass != null) { + aClass.processDeclarations( + new FilterScopeProcessor(new AndFilter(ElementClassFilter.CLASS, new ModifierFilter(PsiModifier.STATIC, false)), + processor), ResolveState.initial(), null, this); + } + } + return; + default: + throw new RuntimeException("Unknown reference type"); } final FilterScopeProcessor proc = new FilterScopeProcessor(filter, processor); PsiScopesUtil.resolveAndWalk(proc, this, null, true); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java index 4f05d58165dc..9e8145fa25a3 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java @@ -213,20 +213,6 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub> } if (value) { - if (parent instanceof PsiField && grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) { - if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.STATIC_KEYWORD || type == JavaTokenType.FINAL_KEYWORD) return; - } - else if (parent instanceof PsiMethod && grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) { - if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.ABSTRACT_KEYWORD) return; - if (type == JavaTokenType.DEFAULT_KEYWORD && findExtensionMethodMarker((PsiMethod)parent) != null) return; - } - else if (parent instanceof PsiClass && grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) { - if (type == JavaTokenType.PUBLIC_KEYWORD) return; - } - else if (parent instanceof PsiAnnotationMethod && grandParent instanceof PsiClass && ((PsiClass)grandParent).isAnnotationType()) { - if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.ABSTRACT_KEYWORD) return; - } - if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.PRIVATE_KEYWORD || type == JavaTokenType.PROTECTED_KEYWORD || @@ -243,6 +229,20 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub> if (type == null) return; } + if (parent instanceof PsiField && grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) { + if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.STATIC_KEYWORD || type == JavaTokenType.FINAL_KEYWORD) return; + } + else if (parent instanceof PsiMethod && grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) { + if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.ABSTRACT_KEYWORD) return; + if (type == JavaTokenType.DEFAULT_KEYWORD && findExtensionMethodMarker((PsiMethod)parent) != null) return; + } + else if (parent instanceof PsiClass && grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) { + if (type == JavaTokenType.PUBLIC_KEYWORD) return; + } + else if (parent instanceof PsiAnnotationMethod && grandParent instanceof PsiClass && ((PsiClass)grandParent).isAnnotationType()) { + if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.ABSTRACT_KEYWORD) return; + } + if (treeElement.findChildByType(type) == null) { TreeElement keyword = Factory.createSingleLeafElement(type, name, null, getManager()); treeElement.addInternal(keyword, keyword, null, null); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java index 1d2ed507b7f2..517ea3197037 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java @@ -105,11 +105,14 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl cachedType = componentType.createArrayType(); } else { + final PsiElement opElement = PsiTreeUtil.skipSiblingsForward(element.getPsi(), PsiWhiteSpace.class); final List<PsiTypeElement> typeElements = PsiTreeUtil.getChildrenOfTypeAsList(this, PsiTypeElement.class); final List<PsiType> types = ContainerUtil.map(typeElements, new Function<PsiTypeElement, PsiType>() { @Override public PsiType fun(final PsiTypeElement psiTypeElement) { return psiTypeElement.getType(); } }); - cachedType = new PsiDisjunctionType(types, getManager()); + cachedType = opElement instanceof PsiJavaToken && ((PsiJavaToken)opElement).getTokenType() == JavaTokenType.AND + ? PsiIntersectionType.createIntersection(types.toArray(new PsiType[types.size()])) + : new PsiDisjunctionType(types, getManager()); } } else if (elementType == JavaElementType.JAVA_CODE_REFERENCE) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java index 39ef8eb5f465..8ae2de30b57d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -20,7 +20,6 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.infos.ClassCandidateInfo; import com.intellij.psi.scope.*; @@ -34,6 +33,7 @@ import java.util.List; public class ClassResolverProcessor extends BaseScopeProcessor implements NameHint, ElementClassHint { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.resolve.ClassResolverProcessor"); private static final String[] DEFAULT_PACKAGES = new String[]{CommonClassNames.DEFAULT_PACKAGE}; + private final String myClassName; private final PsiElement myPlace; private PsiClass myAccessClass = null; @@ -94,14 +94,9 @@ public class ClassResolverProcessor extends BaseScopeProcessor implements NameHi return kind == DeclarationKind.CLASS; } - private boolean myStaticContext = false; - @Override public void handleEvent(PsiScopeProcessor.Event event, Object associated) { - if (event == JavaScopeProcessorEvent.START_STATIC) { - myStaticContext = true; - } - else if (event == JavaScopeProcessorEvent.SET_CURRENT_FILE_CONTEXT) { + if (event == JavaScopeProcessorEvent.SET_CURRENT_FILE_CONTEXT) { myCurrentFileContext = (PsiElement)associated; } } @@ -249,7 +244,7 @@ public class ClassResolverProcessor extends BaseScopeProcessor implements NameHi if (!accessible) return true; if (aClass.hasModifierProperty(PsiModifier.PRIVATE)) { final PsiClass containingPlaceClass = PsiTreeUtil.getParentOfType(myPlace, PsiClass.class, false); - if (containingPlaceClass != null && !PsiTreeUtil.isAncestor(containingPlaceClass, aClass, true)){ + if (containingPlaceClass != null && !PsiTreeUtil.isAncestor(containingPlaceClass, aClass, false)){ return true; } } @@ -257,65 +252,15 @@ public class ClassResolverProcessor extends BaseScopeProcessor implements NameHi } private boolean checkAccessibility(final PsiClass aClass) { - //We don't care about accessibility in javadoc - if (JavaResolveUtil.isInJavaDoc(myPlace)) { - return true; - } - - if (PsiImplUtil.isInServerPage(aClass.getContainingFile())) { - PsiFile file = FileContextUtil.getContextFile(myPlace); - if (PsiImplUtil.isInServerPage(file)) { - return true; - } - } - - boolean accessible = true; - if (aClass instanceof PsiTypeParameter) { - accessible = !myStaticContext; - } - - PsiManager manager = aClass.getManager(); - if (aClass.hasModifierProperty(PsiModifier.PRIVATE)) { - PsiElement parent = aClass.getParent(); - while (true) { - PsiElement parentScope = parent.getParent(); - if (parentScope instanceof PsiJavaFile) break; - parent = parentScope; - if (!(parentScope instanceof PsiClass)) break; - } - if (parent instanceof PsiDeclarationStatement) { - parent = parent.getParent(); - } - accessible = false; - for (PsiElement placeParent = myPlace; placeParent != null; placeParent = placeParent.getContext()) { - if (manager.areElementsEquivalent(placeParent, parent)) accessible = true; - } - } - final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); - if (aClass.hasModifierProperty(PsiModifier.PROTECTED)) { - accessible = false; - if (myPlace != null && facade.arePackagesTheSame(aClass, myPlace)) { - accessible = true; - } - else { - if (aClass.getContainingClass() != null) { - accessible = myAccessClass == null || myPlace != null && facade.getResolveHelper().isAccessible(aClass, myPlace, myAccessClass); - } - } - } - if (aClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { - if (myPlace == null || !facade.arePackagesTheSame(aClass, myPlace)) { - accessible = false; - } - } - return accessible; + JavaPsiFacade facade = JavaPsiFacade.getInstance(aClass.getProject()); + return facade.getResolveHelper().isAccessible(aClass, myPlace, myAccessClass); } @Override public <T> T getHint(@NotNull Key<T> hintKey) { if (hintKey == ElementClassHint.KEY || hintKey == NameHint.KEY) { - //noinspection unchecked - return (T)this; + @SuppressWarnings("unchecked") T t = (T)this; + return t; } return super.getHint(hintKey); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java index 9d927c6832a4..b60524d331ee 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -23,6 +23,7 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.JavaVersionService; import com.intellij.psi.*; import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.util.InheritanceUtil; @@ -49,23 +50,25 @@ public class JavaResolveUtil { } public static boolean isAccessible(@NotNull PsiMember member, - @Nullable final PsiClass memberClass, + @Nullable PsiClass memberClass, @Nullable PsiModifierList modifierList, @NotNull PsiElement place, @Nullable PsiClass accessObjectClass, - @Nullable final PsiElement fileResolveScope) { + @Nullable PsiElement fileResolveScope) { return isAccessible(member, memberClass, modifierList, place, accessObjectClass, fileResolveScope, place.getContainingFile()); } public static boolean isAccessible(@NotNull PsiMember member, - @Nullable final PsiClass memberClass, + @Nullable PsiClass memberClass, @Nullable PsiModifierList modifierList, @NotNull PsiElement place, @Nullable PsiClass accessObjectClass, - @Nullable final PsiElement fileResolveScope, - final PsiFile placeFile) { - if (modifierList == null) return true; - final PsiManager manager = member.getManager(); + @Nullable PsiElement fileResolveScope, + @Nullable PsiFile placeFile) { + if (modifierList == null || isInJavaDoc(place)) { + return true; + } + if (placeFile instanceof JavaCodeFragment) { JavaCodeFragment fragment = (JavaCodeFragment)placeFile; JavaCodeFragment.VisibilityChecker visibilityChecker = fragment.getVisibilityChecker(); @@ -75,35 +78,50 @@ public class JavaResolveUtil { if (visibility == JavaCodeFragment.VisibilityChecker.Visibility.NOT_VISIBLE) return false; } } - else if (ignoreReferencedElementAccessibility(placeFile)) return true; - // We don't care about access rights in javadoc - if (isInJavaDoc(place)) return true; + else if (ignoreReferencedElementAccessibility(placeFile)) { + return true; + } if (accessObjectClass != null) { - if (!isAccessible(accessObjectClass, accessObjectClass.getContainingClass(), accessObjectClass.getModifierList(), place, null, - null, placeFile)) return false; + PsiClass containingClass = accessObjectClass.getContainingClass(); + if (!isAccessible(accessObjectClass, containingClass, accessObjectClass.getModifierList(), place, null, null, placeFile)) { + return false; + } } - int effectiveAccessLevel = PsiUtil.getAccessLevel(modifierList); PsiFile file = placeFile == null ? null : FileContextUtil.getContextFile(placeFile); //TODO: implementation method!!!! - if (PsiImplUtil.isInServerPage(file) && PsiImplUtil.isInServerPage(member.getContainingFile())) return true; - if (ignoreReferencedElementAccessibility(file)) return true; - if (effectiveAccessLevel == PsiUtil.ACCESS_LEVEL_PUBLIC) { + if (PsiImplUtil.isInServerPage(file) && PsiImplUtil.isInServerPage(member.getContainingFile())) { + return true; + } + + int effectiveAccessLevel = PsiUtil.getAccessLevel(modifierList); + if (ignoreReferencedElementAccessibility(file) || effectiveAccessLevel == PsiUtil.ACCESS_LEVEL_PUBLIC) { return true; } + + PsiManager manager = member.getManager(); + JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); + if (effectiveAccessLevel == PsiUtil.ACCESS_LEVEL_PROTECTED) { - if (JavaPsiFacade.getInstance(manager.getProject()).arePackagesTheSame(member, place)) return true; - if (memberClass == null) return false; + if (facade.arePackagesTheSame(member, place)) { + return true; + } + if (memberClass == null) { + return false; + } for (PsiElement placeParent = place; placeParent != null; placeParent = placeParent.getContext()) { if (placeParent instanceof PsiClass && InheritanceUtil.isInheritorOrSelf((PsiClass)placeParent, memberClass, true)) { - if (member instanceof PsiClass || modifierList.hasModifierProperty(PsiModifier.STATIC)) return true; - if (accessObjectClass == null || InheritanceUtil.isInheritorOrSelf(accessObjectClass, (PsiClass)placeParent, true)) return true; + if (member instanceof PsiClass || + modifierList.hasModifierProperty(PsiModifier.STATIC) || + accessObjectClass == null || + InheritanceUtil.isInheritorOrSelf(accessObjectClass, (PsiClass)placeParent, true)) { + return true; + } } } - //if (accessObjectClass != null && accessObjectClass.getManager().areElementsEquivalent(accessObjectClass, memberClass)) return true; - return false; } + if (effectiveAccessLevel == PsiUtil.ACCESS_LEVEL_PRIVATE) { if (memberClass == null) return true; if (accessObjectClass != null) { @@ -122,13 +140,14 @@ public class JavaResolveUtil { !((PsiClass)fileResolveScope).isInheritor(memberClass, true); } } - if (!JavaPsiFacade.getInstance(manager.getProject()).arePackagesTheSame(member, place)) return false; + + if (!facade.arePackagesTheSame(member, place)) return false; if (modifierList.hasModifierProperty(PsiModifier.STATIC)) return true; // maybe inheritance lead through package local class in other package ? final PsiClass placeClass = getContextClass(place); if (memberClass == null || placeClass == null) return true; // check only classes since interface members are public, and if placeClass is interface, - // then its members are static, and cannot refer to nonstatic members of memberClass + // then its members are static, and cannot refer to non-static members of memberClass if (memberClass.isInterface() || placeClass.isInterface()) return true; PsiClass clazz = accessObjectClass != null ? accessObjectClass : @@ -136,7 +155,7 @@ public class JavaResolveUtil { if (clazz != null && clazz.isInheritor(memberClass, true)) { PsiClass superClass = clazz; while (!manager.areElementsEquivalent(superClass, memberClass)) { - if (superClass == null || !JavaPsiFacade.getInstance(manager.getProject()).arePackagesTheSame(superClass, memberClass)) return false; + if (superClass == null || !facade.arePackagesTheSame(superClass, memberClass)) return false; superClass = superClass.getSuperClass(); } } @@ -198,4 +217,17 @@ public class JavaResolveUtil { return true; } + + public static void substituteResults(@NotNull PsiJavaCodeReferenceElement ref, @NotNull JavaResolveResult[] result) { + if (result.length > 0 && result[0].getElement() instanceof PsiClass) { + PsiType[] parameters = ref.getTypeParameters(); + for (int i = 0; i < result.length; i++) { + CandidateInfo resolveResult = (CandidateInfo)result[i]; + PsiElement resultElement = resolveResult.getElement(); + if (resultElement instanceof PsiClass && ((PsiClass)resultElement).hasTypeParameters()) { + result[i] = new CandidateInfo(resolveResult, resolveResult.getSubstitutor().putAll((PsiClass)resultElement, parameters)); + } + } + } + } }
\ No newline at end of file diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java index f67dba0e1a13..e089582e3bc7 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java @@ -36,17 +36,18 @@ public class ProcessCandidateParameterTypeInferencePolicy extends DefaultParamet public static final ProcessCandidateParameterTypeInferencePolicy INSTANCE = new ProcessCandidateParameterTypeInferencePolicy(); @Override - public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiCallExpression innerMethodCall, + public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiExpression innerMethodCall, PsiExpressionList expressionList, PsiCallExpression contextCall, PsiTypeParameter typeParameter) { + PsiExpression[] expressions = expressionList.getExpressions(); + int i = ArrayUtil.find(expressions, innerMethodCall); + if (i < 0) return null; + final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(contextCall); try { //can't call resolve() since it obtains full substitution, that may result in infinite recursion PsiScopesUtil.setupAndRunProcessor(processor, contextCall, false); - PsiExpression[] expressions = expressionList.getExpressions(); - int i = ArrayUtil.find(expressions, innerMethodCall); - if (i < 0) return null; final JavaResolveResult[] results = processor.getResult(); PsiMethod owner = (PsiMethod)typeParameter.getOwner(); if (owner == null) return null; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java index 80f7e0912723..70d50996c84c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -18,6 +18,7 @@ package com.intellij.psi.impl.source.resolve; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.JavaVersionService; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -32,6 +33,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.ArrayUtil; +import com.intellij.util.ArrayUtilRt; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; @@ -45,6 +47,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.resolve.PsiResolveHelperImpl"); public static final Pair<PsiType,ConstraintType> RAW_INFERENCE = new Pair<PsiType, ConstraintType>(null, ConstraintType.EQUALS); private final PsiManager myManager; + public static final Key<PsiCallExpression> CALL_EXPRESSION_KEY = Key.create("methodCall"); public PsiResolveHelperImpl(PsiManager manager) { myManager = manager; @@ -130,12 +133,12 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { @Override public boolean isAccessible(@NotNull PsiMember member, - PsiModifierList modifierList, + @Nullable PsiModifierList modifierList, @NotNull PsiElement place, @Nullable PsiClass accessObjectClass, - final PsiElement currentFileResolveScope) { - return JavaResolveUtil.isAccessible(member, member.getContainingClass(), modifierList, place, accessObjectClass, - currentFileResolveScope); + @Nullable PsiElement currentFileResolveScope) { + PsiClass containingClass = member.getContainingClass(); + return JavaResolveUtil.isAccessible(member, containingClass, modifierList, place, accessObjectClass, currentFileResolveScope); } @Override @@ -221,7 +224,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { if (nullPassed && currentSubstitution == null) return RAW_INFERENCE; } else if (argumentType instanceof PsiMethodReferenceType) { final PsiMethodReferenceExpression referenceExpression = ((PsiMethodReferenceType)argumentType).getExpression(); - currentSubstitution = inferConstraintFromFunctionalInterfaceMethod(typeParameter, referenceExpression, partialSubstitutor.substitute(parameterType)); + currentSubstitution = inferConstraintFromFunctionalInterfaceMethod(typeParameter, referenceExpression, partialSubstitutor.substitute(parameterType), partialSubstitutor, policy); } else { currentSubstitution = getSubstitutionForTypeParameterConstraint(typeParameter, parameterType, @@ -546,7 +549,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { if (arg == null || arg.getDeepComponentType() instanceof PsiPrimitiveType || arg instanceof PsiIntersectionType || - (psiClass != null && (isContraVariantPosition || !CommonClassNames.JAVA_LANG_OBJECT.equals(psiClass.getQualifiedName())))) { + (psiClass != null && (isContraVariantPosition || !CommonClassNames.JAVA_LANG_OBJECT.equals(psiClass.getQualifiedName()) || (arg instanceof PsiArrayType)))) { PsiType bound = intersectAllExtends(typeParam, arg); return new Pair<PsiType, ConstraintType>(bound, ConstraintType.SUPERTYPE); } @@ -608,7 +611,9 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { @Nullable private static Pair<PsiType, ConstraintType> inferConstraintFromFunctionalInterfaceMethod(final PsiTypeParameter typeParam, final PsiMethodReferenceExpression methodReferenceExpression, - final PsiType functionalInterfaceType) { + final PsiType functionalInterfaceType, + final PsiSubstitutor partialSubstitutor, + final ParameterTypeInferencePolicy policy) { final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); final PsiMethod functionalInterfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult); if (functionalInterfaceMethod != null) { @@ -669,7 +674,14 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { } else { argType = methReferenceResolveResult.getSubstitutor().substitute(subst.substitute(method.getReturnType())); } - return getSubstitutionForTypeParameterConstraint(typeParam, functionalInterfaceReturnType, argType, true, PsiUtil.getLanguageLevel(functionalInterfaceMethod)); + final Pair<PsiType, ConstraintType> typeParameterConstraint = + getSubstitutionForTypeParameterConstraint(typeParam, functionalInterfaceReturnType, argType, true, PsiUtil.getLanguageLevel(functionalInterfaceMethod)); + if (typeParameterConstraint != null && typeParameterConstraint.getSecond() != ConstraintType.EQUALS && method.isConstructor()) { + final Pair<PsiType, ConstraintType> constraintFromParent = + inferMethodTypeParameterFromParent(typeParam, partialSubstitutor, methodReferenceExpression.getParent().getParent(), policy); + if (constraintFromParent != null && constraintFromParent.getSecond() == ConstraintType.EQUALS) return constraintFromParent; + } + return typeParameterConstraint; } } } @@ -689,7 +701,8 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { if (constraintFromFormalParams != null) return constraintFromFormalParams; final PsiParameter[] methodParameters = method.getParameterList().getParameters(); - if (methodParamsDependOn(typeParam, lambdaExpression, functionalInterfaceType, methodParameters, subst)) { + if (methodParamsDependOn(typeParam, lambdaExpression, functionalInterfaceType, methodParameters, subst)) { + //todo should always return null for b.72 if (lowerBound != PsiType.NULL) { return null; } @@ -723,6 +736,8 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { } else if (exprType instanceof PsiLambdaExpressionType) { return inferConstraintFromFunctionalInterfaceMethod(typeParam, ((PsiLambdaExpressionType)exprType).getExpression(), returnType, lowerBound); + } else if (exprType == null && independent) { + return null; } if (exprType == null){ @@ -923,6 +938,12 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { final PsiTypeParameter typeParameter, PsiSubstitutor substitutor, ParameterTypeInferencePolicy policy) { + final PsiCallExpression preparedKey = methodCall.getCopyableUserData(CALL_EXPRESSION_KEY); + if (preparedKey != null) { + parent = parent.getContext(); + methodCall = preparedKey; + } + Pair<PsiType, ConstraintType> constraint = null; PsiType expectedType = null; @@ -952,9 +973,14 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { } else if (parent instanceof PsiExpressionList) { final PsiElement pParent = parent.getParent(); - if (pParent instanceof PsiCallExpression && parent.equals(((PsiCallExpression)pParent).getArgumentList())) { - constraint = policy.inferTypeConstraintFromCallContext(methodCall, (PsiExpressionList)parent, (PsiCallExpression)pParent, - typeParameter); + if (pParent instanceof PsiCallExpression && parent.equals(((PsiCallExpression)pParent).getArgumentList())) { + constraint = policy.inferTypeConstraintFromCallContext(methodCall, (PsiExpressionList)parent, (PsiCallExpression)pParent, typeParameter); + if (constraint == null && PsiUtil.isLanguageLevel8OrHigher(methodCall)) { + constraint = graphInferenceFromCallContext(methodCall, typeParameter, (PsiCallExpression)pParent); + if (constraint != null && constraint.getFirst().equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) { + constraint = null; + } + } } } else if (parent instanceof PsiLambdaExpression) { expectedType = LambdaUtil.getFunctionalInterfaceReturnType(((PsiLambdaExpression)parent).getFunctionalInterfaceType()); @@ -1015,6 +1041,9 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { } return null; } + if (preparedKey != null) { + return getFailedInferenceConstraint(typeParameter); + } } } } @@ -1053,4 +1082,27 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { } return result; } + + private static Pair<PsiType, ConstraintType> graphInferenceFromCallContext(@NotNull PsiCallExpression methodCall, + @NotNull PsiTypeParameter typeParameter, + @NotNull PsiCallExpression parentCall) { + final PsiExpressionList argumentList = parentCall.getArgumentList(); + LOG.assertTrue(argumentList != null); + final int exprIdx = ArrayUtilRt.find(argumentList.getExpressions(), PsiUtil.skipParenthesizedExprUp(methodCall)); + + if (exprIdx > -1) { + final PsiExpression nullPlaceholder = JavaPsiFacade.getElementFactory(methodCall.getProject()).createExpressionFromText("null", methodCall); + + final PsiCallExpression copy = (PsiCallExpression)parentCall.copy(); + final PsiExpressionList copyArgumentList = copy.getArgumentList(); + LOG.assertTrue(copyArgumentList != null); + final PsiExpression currentCallInCopy = copyArgumentList.getExpressions()[exprIdx]; + + final PsiExpression methodCallCopy = (PsiExpression)currentCallInCopy.replace(nullPlaceholder); + copy.putCopyableUserData(CALL_EXPRESSION_KEY, parentCall); + return ProcessCandidateParameterTypeInferencePolicy.INSTANCE + .inferTypeConstraintFromCallContext(methodCallCopy, copyArgumentList, copy, typeParameter); + } + return null; + } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiPostfixExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiPostfixExpressionImpl.java index 6f6f0f4d36dd..e2aeb4c13e09 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiPostfixExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiPostfixExpressionImpl.java @@ -51,9 +51,7 @@ public class PsiPostfixExpressionImpl extends ExpressionPsiElement implements Ps @Override public PsiType getType() { - PsiType type = getOperand().getType(); - if (type instanceof PsiClassType) type = PsiPrimitiveType.getUnboxedType(type); - return type; + return getOperand().getType(); } @Override diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiPrefixExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiPrefixExpressionImpl.java index 0bda2b5f3b3b..2590a75a9167 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiPrefixExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiPrefixExpressionImpl.java @@ -54,10 +54,10 @@ public class PsiPrefixExpressionImpl extends ExpressionPsiElement implements Psi PsiExpression operand = getOperand(); if (operand == null) return null; PsiType type = operand.getType(); - if (type instanceof PsiClassType) type = PsiPrimitiveType.getUnboxedType(type); IElementType opCode = getOperationTokenType(); if (opCode == JavaTokenType.PLUS || opCode == JavaTokenType.MINUS || opCode == JavaTokenType.TILDE) { if (type == null) return null; + if (type instanceof PsiClassType) type = PsiPrimitiveType.getUnboxedType(type); return PsiType.BYTE.equals(type) || PsiType.CHAR.equals(type) || PsiType.SHORT.equals(type) ? PsiType.INT : type; } else if (opCode == JavaTokenType.PLUSPLUS || opCode == JavaTokenType.MINUSMINUS) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java index 7375daa7f057..fdb1609faef4 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -34,10 +34,7 @@ import com.intellij.psi.impl.PsiManagerEx; import com.intellij.psi.impl.source.SourceJavaCodeReference; import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; -import com.intellij.psi.impl.source.resolve.ClassResolverProcessor; -import com.intellij.psi.impl.source.resolve.JavaResolveCache; -import com.intellij.psi.impl.source.resolve.ResolveCache; -import com.intellij.psi.impl.source.resolve.VariableResolverProcessor; +import com.intellij.psi.impl.source.resolve.*; import com.intellij.psi.impl.source.tree.*; import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.scope.ElementClassFilter; @@ -187,59 +184,46 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple private static final class OurGenericsResolver implements ResolveCache.PolyVariantResolver<PsiJavaReference> { private static final OurGenericsResolver INSTANCE = new OurGenericsResolver(); + @Override @NotNull - private static JavaResolveResult[] _resolve(boolean incompleteCode, PsiReferenceExpressionImpl expression) { + public JavaResolveResult[] resolve(@NotNull PsiJavaReference ref, boolean incompleteCode) { + PsiReferenceExpressionImpl expression = (PsiReferenceExpressionImpl)ref; CompositeElement treeParent = expression.getTreeParent(); IElementType parentType = treeParent == null ? null : treeParent.getElementType(); - expression.resolveAllQualifiers(); - final JavaResolveResult[] result = expression.resolve(parentType); + resolveAllQualifiers(expression); + JavaResolveResult[] result = expression.resolve(parentType); - if (incompleteCode && parentType != JavaElementType.REFERENCE_EXPRESSION && result.length == 0) { - return expression.resolve(JavaElementType.REFERENCE_EXPRESSION); + if (result.length == 0 && incompleteCode && parentType != JavaElementType.REFERENCE_EXPRESSION) { + result = expression.resolve(JavaElementType.REFERENCE_EXPRESSION); } - return result; - } + JavaResolveUtil.substituteResults(expression, result); - @Override - @NotNull - public JavaResolveResult[] resolve(@NotNull PsiJavaReference ref, boolean incompleteCode) { - final JavaResolveResult[] result = _resolve(incompleteCode, (PsiReferenceExpressionImpl)ref); - if (result.length > 0 && result[0].getElement() instanceof PsiClass) { - final PsiType[] parameters = ((PsiJavaCodeReferenceElement)ref).getTypeParameters(); - final JavaResolveResult[] newResult = new JavaResolveResult[result.length]; - for (int i = 0; i < result.length; i++) { - final CandidateInfo resolveResult = (CandidateInfo)result[i]; - newResult[i] = new CandidateInfo(resolveResult, resolveResult.getSubstitutor().putAll( - (PsiClass)resolveResult.getElement(), parameters)); - } - return newResult; - } return result; } - } - private void resolveAllQualifiers() { - // to avoid SOE, resolve all qualifiers starting from the innermost - PsiElement qualifier = getQualifier(); - if (qualifier == null) return; - final ResolveCache resolveCache = ResolveCache.getInstance(getProject()); - qualifier.accept(new JavaRecursiveElementWalkingVisitor() { - @Override - public void visitReferenceExpression(PsiReferenceExpression expression) { - if (!(expression instanceof PsiReferenceExpressionImpl) || resolveCache.isCached(expression, true, false, true)) { - return; + private static void resolveAllQualifiers(PsiReferenceExpressionImpl expression) { + // to avoid SOE, resolve all qualifiers starting from the innermost + PsiElement qualifier = expression.getQualifier(); + if (qualifier == null) return; + final ResolveCache resolveCache = ResolveCache.getInstance(expression.getProject()); + qualifier.accept(new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { + if (!(expression instanceof PsiReferenceExpressionImpl) || resolveCache.isCached(expression, true, false, true)) { + return; + } + visitElement(expression); } - visitElement(expression); - } - @Override - protected void elementFinished(PsiElement element) { - if (!(element instanceof PsiReferenceExpressionImpl)) return; - PsiReferenceExpressionImpl expression = (PsiReferenceExpressionImpl)element; - resolveCache.resolveWithCaching(expression, OurGenericsResolver.INSTANCE, false, false); - } - }); + @Override + protected void elementFinished(PsiElement element) { + if (!(element instanceof PsiReferenceExpressionImpl)) return; + PsiReferenceExpressionImpl expression = (PsiReferenceExpressionImpl)element; + resolveCache.resolveWithCaching(expression, INSTANCE, false, false); + } + }); + } } @NotNull @@ -250,21 +234,33 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple return result; } - final PsiElement classNameElement = getReferenceNameElement(); - if (!(classNameElement instanceof PsiIdentifier)) return JavaResolveResult.EMPTY_ARRAY; + PsiElement classNameElement = getReferenceNameElement(); + if (!(classNameElement instanceof PsiIdentifier)) { + return JavaResolveResult.EMPTY_ARRAY; + } + result = resolveToClass(classNameElement); - if (result.length > 0) { - return result; + if (result.length == 1 && !result[0].isAccessible()) { + JavaResolveResult[] packageResult = resolveToPackage(); + if (packageResult.length != 0) { + result = packageResult; + } + } + else if (result.length == 0) { + result = resolveToPackage(); } - return resolveToPackage(); + return result; } + if (parentType == JavaElementType.METHOD_CALL_EXPRESSION) { return resolveToMethod(); } + if (parentType == JavaElementType.METHOD_REF_EXPRESSION) { return resolve(JavaElementType.REFERENCE_EXPRESSION); } + return resolveToVariable(); } diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java index f7946b85b4e9..b6d8f1bd93a7 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java @@ -123,9 +123,10 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ } } } + LambdaUtil.checkMoreSpecificReturnType(conflicts, i); } else if (parameterType instanceof PsiMethodReferenceType) { - PsiMethodReferenceUtil.processMethodReferenceReturnType(conflicts, i); + LambdaUtil.checkMoreSpecificReturnType(conflicts, i); } } } @@ -583,6 +584,12 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ if (map1.size() == 1 && map2.size() == 1) { final PsiType t1 = map1.values().iterator().next(); final PsiType t2 = map2.values().iterator().next(); + + boolean raw1 = t1 instanceof PsiClassType && ((PsiClassType)t1).hasParameters(); + boolean raw2 = t2 instanceof PsiClassType && ((PsiClassType)t2).hasParameters(); + if (!raw1 && raw2) return Specifics.FIRST; + if (raw1 && !raw2) return Specifics.SECOND; + final Specifics substArraySpecifics = chooseHigherDimension(t1, t2); if (substArraySpecifics != null) { return substArraySpecifics; diff --git a/java/java-psi-impl/src/messages/JavaErrorMessages.properties b/java/java-psi-impl/src/messages/JavaErrorMessages.properties index 1b02a298c40f..b44bf6eebbe5 100644 --- a/java/java-psi-impl/src/messages/JavaErrorMessages.properties +++ b/java/java-psi-impl/src/messages/JavaErrorMessages.properties @@ -150,6 +150,9 @@ repeated.annotation.target=Repeated annotation target clash.methods.message=''{0}'' clashes with ''{1}'' clash.methods.message.show.classes=''{0}'' in ''{2}'' clashes with ''{1}'' in ''{3}'' +package.clashes.with.class=Package ''{0}'' clashes with class of same name +class.clashes.with.package=Class ''{0}'' clashes with package of same name + # {0} - colspan, {1} - method1, {2} - class1, {3} - method2, {4} - class2 ambiguous.method.html.tooltip=\ <html><body><table border=0>\ @@ -278,6 +281,7 @@ unclosed.char.literal=Unclosed character literal illegal.escape.character.in.string.literal=Illegal escape character in string literal floating.point.number.too.large=Floating point number too large floating.point.number.too.small=Floating point number too small +illegal.underscore=Illegal underscore import.statement.identifier.or.asterisk.expected.=Identifier or '*' expected diff --git a/java/java-tests/testData/codeInsight/completion/javadoc/QualifyClassReferenceInPackageStatement.java b/java/java-tests/testData/codeInsight/completion/javadoc/QualifyClassReferenceInPackageStatement.java new file mode 100644 index 000000000000..e92cc86cc8eb --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/javadoc/QualifyClassReferenceInPackageStatement.java @@ -0,0 +1,8 @@ +/** + * @see XHell<caret> + */ +package foo.bar; + +class XHello { + +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/javadoc/QualifyClassReferenceInPackageStatement_after.java b/java/java-tests/testData/codeInsight/completion/javadoc/QualifyClassReferenceInPackageStatement_after.java new file mode 100644 index 000000000000..8cbb31c1688f --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/javadoc/QualifyClassReferenceInPackageStatement_after.java @@ -0,0 +1,8 @@ +/** + * @see foo.bar.XHello<caret> + */ +package foo.bar; + +class XHello { + +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/keywords/arrayClass.java b/java/java-tests/testData/codeInsight/completion/keywords/arrayClass.java new file mode 100644 index 000000000000..80690075bcea --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/keywords/arrayClass.java @@ -0,0 +1,5 @@ +public class Util { + int goo() { + String[].<caret>x + } +} diff --git a/java/java-tests/testData/codeInsight/completion/keywords/finalAfterCase.java b/java/java-tests/testData/codeInsight/completion/keywords/finalAfterCase.java new file mode 100644 index 000000000000..0d201763da54 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/keywords/finalAfterCase.java @@ -0,0 +1,8 @@ +public class StructuredConfigKey { + { + switch (x) { + case 2: + <caret> + } + } +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/ImplementViaCompletion.java b/java/java-tests/testData/codeInsight/completion/normal/ImplementViaCompletion.java new file mode 100644 index 000000000000..85d7845803d8 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/ImplementViaCompletion.java @@ -0,0 +1,7 @@ +interface Foo<T> { + void run(T t, int myInt); +} + +public class A implements Foo<String> { + p<caret> +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/ImplementViaCompletion_after.java b/java/java-tests/testData/codeInsight/completion/normal/ImplementViaCompletion_after.java new file mode 100644 index 000000000000..a13b20e89807 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/ImplementViaCompletion_after.java @@ -0,0 +1,10 @@ +interface Foo<T> { + void run(T t, int myInt); +} + +public class A implements Foo<String> { + @Override + public void run(String s, int myInt) { + <selection>//To change body of implemented methods use File | Settings | File Templates.</selection> + } +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/TypeParameterItemPresentation.java b/java/java-tests/testData/codeInsight/completion/normal/TypeParameterItemPresentation.java new file mode 100644 index 000000000000..c56297de58d7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/TypeParameterItemPresentation.java @@ -0,0 +1,5 @@ +public class Foo<Param> { + <Param2> int goo() { + Pa<caret> + } +} diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/AlphaSortingStartMatchesFirst.java b/java/java-tests/testData/codeInsight/completion/normalSorting/AlphaSortingStartMatchesFirst.java new file mode 100644 index 000000000000..87423fdc5cfb --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/AlphaSortingStartMatchesFirst.java @@ -0,0 +1,12 @@ +class Goo { + { + int xxfoo; + int fooxx; + int xxgoo; + int gooxx; + int xxbar; + int barxx; + xx<caret> + } + +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/LocalVarsOverStats.java b/java/java-tests/testData/codeInsight/completion/normalSorting/LocalVarsOverStats.java new file mode 100644 index 000000000000..ec010fe2ac72 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/LocalVarsOverStats.java @@ -0,0 +1,8 @@ +public class Foo { + + void foo(PsiElement psiElement) { + psiEl<caret> + } +} + +class PsiElement {}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/ArrayInitializerBeforeVarargs-out.java b/java/java-tests/testData/codeInsight/completion/smartType/ArrayInitializerBeforeVarargs-out.java index bec60ac2de6b..49ce3eb54d4b 100644 --- a/java/java-tests/testData/codeInsight/completion/smartType/ArrayInitializerBeforeVarargs-out.java +++ b/java/java-tests/testData/codeInsight/completion/smartType/ArrayInitializerBeforeVarargs-out.java @@ -1,5 +1,5 @@ class Super { void foo(String[] params, int... indices) { - foo(new String[]{<caret>}, 0); + foo(new String[<caret>], 0); } }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/IgnoreDefaultMethods-out.java b/java/java-tests/testData/codeInsight/completion/smartType/IgnoreDefaultMethods-out.java new file mode 100644 index 000000000000..f6b90f287be6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/IgnoreDefaultMethods-out.java @@ -0,0 +1,18 @@ +interface Predicate<T> { + public boolean test(T t); + public default Predicate<T> and(Predicate<? super T> p) { + return null; + } +} + + +public class Test1 { + { + Predicate p = new Predicate() { + @Override + public boolean test(Object o) { + <selection>return false; //To change body of implemented methods use File | Settings | File Templates.</selection> + } + }; + } +} diff --git a/java/java-tests/testData/codeInsight/completion/smartType/IgnoreDefaultMethods.java b/java/java-tests/testData/codeInsight/completion/smartType/IgnoreDefaultMethods.java new file mode 100644 index 000000000000..ea35c5cb45c5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/IgnoreDefaultMethods.java @@ -0,0 +1,13 @@ +interface Predicate<T> { + public boolean test(T t); + public default Predicate<T> and(Predicate<? super T> p) { + return null; + } +} + + +public class Test1 { + { + Predicate p = new Predic<caret> + } +} diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInCodeBlocBodyInLocalVariable.java b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInCodeBlocBodyInLocalVariable.java index fa6f209bf19b..e98107784592 100644 --- a/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInCodeBlocBodyInLocalVariable.java +++ b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInCodeBlocBodyInLocalVariable.java @@ -1,5 +1,5 @@ class Test { public void foo() { - Runnable r = () -> {<caret>}; + Runnable r = () -> {n<caret>}; } } diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInExpressionList.java b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInExpressionList.java index 7b403c035879..a9a9766a2724 100644 --- a/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInExpressionList.java +++ b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInExpressionList.java @@ -1,5 +1,5 @@ class Test { public void foo() { - new Thread(() -> <caret>); + new Thread(() -> n<caret>); } } diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInLocalVariable.java b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInLocalVariable.java index e41c2a19a0d3..b0dee48e23d7 100644 --- a/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInLocalVariable.java +++ b/java/java-tests/testData/codeInsight/completion/smartType/SemicolonInExpressionBodyInLocalVariable.java @@ -1,5 +1,5 @@ class Test { public void foo() { - Runnable r = () -> <caret> + Runnable r = () -> n<caret> } } diff --git a/java/java-tests/testData/codeInsight/completion/smartType/ThrowExceptionConstructor-out.java b/java/java-tests/testData/codeInsight/completion/smartType/ThrowExceptionConstructor-out.java index 7d740e51351c..d105afd9a5d7 100644 --- a/java/java-tests/testData/codeInsight/completion/smartType/ThrowExceptionConstructor-out.java +++ b/java/java-tests/testData/codeInsight/completion/smartType/ThrowExceptionConstructor-out.java @@ -4,6 +4,6 @@ class MyException extends RuntimeException { class XXX { { - throw new MyException(new String[]{<caret>}); + throw new MyException(new String[<caret>]); } }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassConstantReference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassConstantReference.java new file mode 100644 index 000000000000..ba341f1b7489 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassConstantReference.java @@ -0,0 +1,11 @@ +class Test { + public Test() { + this(Const.CONST); + } + + public Test(int l) {} + + private class Const { + private static final int CONST = 42; + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassesShadowing.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassesShadowing.java index e87c5db28998..647df2b9e7b0 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassesShadowing.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassesShadowing.java @@ -95,4 +95,18 @@ class WithFileInputStream { private FileInputStream(String str) { } } -}
\ No newline at end of file +} + +class ContainingKlass { + public static class Inner { + } + + private static class OuterInner { + private static final class Inner { + private Inner s() { + return this; + } + } + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/NumericLiterals.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/NumericLiterals.java index becdda581a2a..45f728d465f8 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/NumericLiterals.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/NumericLiterals.java @@ -1,24 +1,4 @@ -/* - * 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. - */ - -/// assignment compatible types -import java.io.*; -import java.net.*; - -public class a { +public class NumericLiterals { final int FI = 2; final int FIBIG = 200000000; @@ -38,7 +18,8 @@ public class a { int i13 = <error descr="Integer number too large">040000000000</error>; int i14 = 020000000000; int i15 = <error descr="Integer number too large">0xf044332211</error>; - int octale = 017777777777; // negative + int oi1 = 017777777777; + int oi2 = <error descr="Integer number too large">08</error>; int bi1 = <error descr="Binary literals are not supported at this language level">0b0010</error>; int bi2 = <error descr="Binary literals are not supported at this language level">0B0010</error>; int bi3 = <error descr="Underscores in literals are not supported at this language level">1_2</error>; @@ -53,8 +34,8 @@ public class a { long l8 = 0xffffffffffffffffL; long l9 = <error descr="Long number too large">0xffffffffffffffff9L</error>; long l10 = 0x8000000000000000L; - long octalValue = 01777777777777777777600L; - long octalValua = 01777777777777777777777L; + long ol1 = 01777777777777777777600L; + long ol2 = 01777777777777777777777L; long bl1 = <error descr="Binary literals are not supported at this language level">0b0010l</error>; long bl2 = <error descr="Binary literals are not supported at this language level">0B0010L</error>; long bl3 = <error descr="Underscores in literals are not supported at this language level">10_24L</error>; @@ -63,7 +44,8 @@ public class a { float f2 = <error descr="Floating point number too large">1e39f</error>; float f3 = 0E1F; float f4 = <error descr="Hexadecimal floating point literals are not supported at this language level">0xabc.defP2f</error>; - float bf1 = <error descr="Underscores in literals are not supported at this language level">3.141_592f</error>; + float f5 = <error descr="Underscores in literals are not supported at this language level">3.141_592f</error>; + float f6 = .0f; double dd1 = <error descr="Floating point number too small">1e-324</error>; double dd2 = <error descr="Floating point number too large">1e309</error>; @@ -81,5 +63,6 @@ public class a { double d10 = <error descr="Malformed floating point literal">1e-F</error>; double d11 = <error descr="Malformed floating point literal">1e-f</error>; double d12 = <error descr="Underscores in literals are not supported at this language level">3.141_592_653_589_793d</error>; + double d13 = <error descr="Malformed floating point literal">.0e</error>; } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/importDefaultPackage/Test.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/importDefaultPackage/Test.java index 64f17b3299c0..6402fa536bbc 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/importDefaultPackage/Test.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/importDefaultPackage/Test.java @@ -1,4 +1,5 @@ public class Test { public Test(int i) { + new x(); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/importDefaultPackage/x.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/importDefaultPackage/x.java new file mode 100644 index 000000000000..88b90d97d842 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/importDefaultPackage/x.java @@ -0,0 +1 @@ +class x { } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/lang.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/lang.java new file mode 100644 index 000000000000..39f8b0f7f30c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/lang.java @@ -0,0 +1,3 @@ +package java; + +<error descr="Class 'java.lang' clashes with package of same name">class lang</error> { } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageClassClash1/pkg/sub.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageClassClash1/pkg/sub.java new file mode 100644 index 000000000000..3b442d2610ac --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageClassClash1/pkg/sub.java @@ -0,0 +1,3 @@ +package pkg; + +<error descr="Class 'pkg.sub' clashes with package of same name">public class sub</error> { }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageClassClash1/pkg/sub/Test.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageClassClash1/pkg/sub/Test.java new file mode 100644 index 000000000000..f2dbcbd38b91 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageClassClash1/pkg/sub/Test.java @@ -0,0 +1,3 @@ +package <error descr="Package 'pkg.sub' clashes with class of same name">pkg.sub</error>; + +public class Test { }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageClassClash2/pkg/Sub.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageClassClash2/pkg/Sub.java new file mode 100644 index 000000000000..bea47a75e0e3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageClassClash2/pkg/Sub.java @@ -0,0 +1,3 @@ +package pkg; + +public class Sub { }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageClassClash2/pkg/sub/Test.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageClassClash2/pkg/sub/Test.java new file mode 100644 index 000000000000..bf2f203764d6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageClassClash2/pkg/sub/Test.java @@ -0,0 +1,3 @@ +package pkg.sub; + +public class Test { }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageObscuring/main/Main.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageObscuring/main/Main.java new file mode 100644 index 000000000000..ec7d7e6611ae --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageObscuring/main/Main.java @@ -0,0 +1,12 @@ +package main; + +public class Main { + public static void main(String[] args) { + pkg.sub.Test obj = new pkg.sub.Test(); + obj.m1(); + obj.<error descr="Cannot resolve method 'm2()'">m2</error>(); + + pkg.sub.Test.s1(); + pkg.sub.Test.<error descr="Cannot resolve method 's2()'">s2</error>(); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageObscuring/pkg/sub.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageObscuring/pkg/sub.java new file mode 100644 index 000000000000..21764febddbc --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageObscuring/pkg/sub.java @@ -0,0 +1,9 @@ +package pkg; + +class sub { + public static class Test { + public void m2() { } + + public static void s2() { } + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageObscuring/pkg/sub/Test.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageObscuring/pkg/sub/Test.java new file mode 100644 index 000000000000..90c5d6ebfb13 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/packageObscuring/pkg/sub/Test.java @@ -0,0 +1,7 @@ +package pkg.sub; + +public class Test { + public void m1() { } + + public static void s1() { } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/JavacQuirks.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/JavacQuirks.java index e95529cd16c1..e95529cd16c1 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/JavacQuirks.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/JavacQuirks.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/AmbiguousMethodCallIDEA100314.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/AmbiguousMethodCallIDEA100314.java new file mode 100644 index 000000000000..2c155443365c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/AmbiguousMethodCallIDEA100314.java @@ -0,0 +1,13 @@ +class Intellij { + + public static <T> T getProperty(final String str, final Class<T> cls) { + return null; + } + + public static <T> T getProperty(final String str, final T defaultValue) { + return null; + } + + String[] ids = Intellij.getProperty(" ", String[].class); + +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/NumericLiterals.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/NumericLiterals.java index bf9f96ff1e96..cb59ded58cc6 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/NumericLiterals.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/NumericLiterals.java @@ -7,6 +7,11 @@ public class NumericLiterals { int i5 = 0b0001_0010_0100_1000; int i6 = <error descr="Binary numbers must contain at least one binary digit">0b</error>; int i7 = <error descr="Integer number too large">0b1_1111_1111_1111_1111_1111_1111_1111_1111</error>; + int i8 = <error descr="Illegal underscore">0_</error>; + int i9 = <error descr="Integer number too large">0_8</error>; + int i10 = <error descr="Illegal underscore">0x_f</error>; + int i11 = <error descr="Illegal underscore">0b_1</error>; + int i12 = <error descr="Integer number too large">0B2</error>; long l1 = 1_2L; long l2 = 012__34l; @@ -41,5 +46,7 @@ public class NumericLiterals { double d10 = 0x.a_bcP1___23d; double d11 = <error descr="Floating point number too small">1e-3_2_4</error>; double d12 = <error descr="Floating point number too large">0xa_bc.de_fP1_234D</error>; + double d13 = <error descr="Illegal underscore">0x1.0_p-1</error>; + double d14 = <error descr="Illegal underscore">1.0e_1022</error>; } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedWarningIDEA99357.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedWarningIDEA99357.java new file mode 100644 index 000000000000..e6635ac196f4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedWarningIDEA99357.java @@ -0,0 +1,12 @@ +class Test { + public static void main(String[] args) { + Foo f = new Foo(); + System.out.println(f.get()); + } +} + +class Foo<<warning descr="Type parameter 'T' is never used">T</warning>> { + public <T1> T1 get() { + return null; + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedWarningIDEA99536.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedWarningIDEA99536.java new file mode 100644 index 000000000000..7cab4aff7f31 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedWarningIDEA99536.java @@ -0,0 +1,29 @@ +import java.util.*; +class A<<warning descr="Type parameter 'T' is never used">T</warning>> { +} + +class B<<warning descr="Type parameter 'S' is never used">S</warning>> extends A { +} + +class C extends A<String> { +} + + +class D extends A { +} + + +public class Main { + public static void test(Collection<? extends A> <warning descr="Parameter 'c' is never used">c</warning>) {} + + public static void main(String[] args) { + Collection<B> bs = new ArrayList<B>(); + test(bs); + + Collection<C> cs = new ArrayList<C>(); + test(cs); + + Collection<D> ds = new ArrayList<D>(); + test(ds); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA86875.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA86875.java new file mode 100644 index 000000000000..c5a65df099ab --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA86875.java @@ -0,0 +1,11 @@ +interface Base<E> {} +interface Base2<E> {} + +class A<E extends Cloneable> { + <P, K extends Base<E>&Base2<P>> void m(K k, P p) { + E e = null; + m(k, e); + } + + void m(Base<E> k, E e) {} +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA99061.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA99061.java new file mode 100644 index 000000000000..b6e8f3cfa619 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA99061.java @@ -0,0 +1,11 @@ +class Test { + { + String a = cast("str"); + Integer[] b = cast(new Integer[0]); + Object[] c = cast(new Object[0]); + } + + private <T> T cast(Object obj) { + return (T)obj; + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA99347.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA99347.java new file mode 100644 index 000000000000..9c4922400b7d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA99347.java @@ -0,0 +1,12 @@ +interface Errors { + java.util.Collection<java.lang.String> getErrorMessages(); + +} + +class Test extends AbstrClass implements Errors { +} + + +abstract class AbstrClass { + public java.util.Collection getErrorMessages() {return null;} +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/ChainedInference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/ChainedInference.java new file mode 100644 index 000000000000..49c813e2a878 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/ChainedInference.java @@ -0,0 +1,26 @@ +import java.util.*; + +class Main { + + void foo(List<Integer> list) { + bar(list, i -> i.intValue(), i -> i.<error descr="Cannot resolve method 'unknown()'">unknown</error>()); + bar1(list, i -> i.intValue(), i -> i.<error descr="Cannot resolve method 'unknown()'">unknown</error>()); + } + + <U, S_IN, S_OUT, R> R bar(List<S_IN> list, + Fun<S_IN, S_OUT> f1, + Fun<S_OUT, R> f2) { + return null; + } + + <R, S_IN, S_OUT> R bar1(List<S_IN> list, + Fun<S_IN, S_OUT> f1, + Fun<S_OUT, R> f2) { + return null; + } + + + public interface Fun<T, R> { + public R _(T t); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/ChainedInference1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/ChainedInference1.java new file mode 100644 index 000000000000..3033b3971428 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/ChainedInference1.java @@ -0,0 +1,14 @@ +class Main { + + <R> void bar(Fun<Integer, R> collector) { } + + <T, D> Fun<T, Integer> foo(D d) { return null; } + + public void test() { + bar(foo("")); + } + + interface Fun<T, R> { + R _(T t); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/InferenceFromSiblings.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/InferenceFromSiblings.java new file mode 100644 index 000000000000..1cad86808b98 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/InferenceFromSiblings.java @@ -0,0 +1,24 @@ +import java.util.*; + +class Main { + + void test(List<Integer> li) { + Fun<Stream<Integer>, Stream<Integer>> f = s -> s.substr(0); + foo(li, f, Collections.emptyList()); + + foo(li, s -> s.substr(0), Collections.emptyList()); + } + + <T, U, S_OUT extends Stream<U>, It extends Iterable<U>> Collection<U> + foo(Collection<T> coll, Fun<Stream<T>, S_OUT> f, It it) { + return null; + } + + interface Stream<T> { + Stream<T> substr(long startingOffset); + } + + interface Fun<T, R> { + R _(T t); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCalls.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCalls.java new file mode 100644 index 000000000000..0c91d21fdbfd --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCalls.java @@ -0,0 +1,15 @@ +import java.util.*; +public class Main { + public static <T> T foo() {return null;} + + public static <B> List<B> bar(B b) {return null;} + static { + List<String> s = bar(foo()); + } + + + public static <B> B bar1(B b) {return null;} + static { + String s1 = bar1(foo()); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCallsSameMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCallsSameMethod.java new file mode 100644 index 000000000000..e4d33d38747f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/NestedCallsSameMethod.java @@ -0,0 +1,9 @@ +class Main { + static <T> T foo(T t) { return null; } + + static { + long l1 = foo(foo(1)); + Integer i = 1; + long l2 = foo(foo(i)); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/ReturnStmt.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/ReturnStmt.java new file mode 100644 index 000000000000..dae02b68773f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/ReturnStmt.java @@ -0,0 +1,27 @@ +import java.util.*; +class Main { + + <T, R> Collector<T, R> m(Supplier<? extends R> supplier, BiConsumer<R, T> accumulator) { + return null; + } + + <T, C extends Collection<T>> Collector<T, C> test1(Supplier<C> collectionFactory) { + return m(collectionFactory, Collection::add); + } + + Collector<String, StringBuilder> test2(Supplier<StringBuilder> sb) { + return m(sb, StringBuilder::append); + } + + interface Supplier<T> { + public T get(); + } + + interface Collector<T, R> { + } + + interface BiConsumer<T, U> { + void accept(T t, U u); + } + +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution.java new file mode 100644 index 000000000000..43c4ba966b7b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution.java @@ -0,0 +1,26 @@ +public interface IDEA99969 { + default IntStream distinct(Stream s) { + return s.map(i -> (int) i); + } +} +interface Stream<T> { + <R> Stream<R> map(Function<? super T, ? extends R> mapper); + IntStream map(IntFunction<? super T> mapper); + LongStream map(LongFunction<? super T> mapper); +} + +interface Function<T, R> { + public R apply(T t); +} + +interface IntFunction<T> { + public int applyAsInt(T t); +} + +interface LongFunction<T> { + public long applyAsLong(T t); +} + + +interface IntStream {} +interface LongStream {} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguitySpecificReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguitySpecificReturn.java new file mode 100644 index 000000000000..c0908783911c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguitySpecificReturn.java @@ -0,0 +1,30 @@ +class IntStream { + private void foo(IntStream s) { + s.map(i -> 1 << i); + s.map(i -> 1); + s.map(i -> i); + } + + public static void main(String[] args) { + new IntStream().foo(null); + } + + private IntStream map(IntUnaryOperator mapper) { + System.out.println(mapper); + return null; + } + + private <T> IntStream <warning descr="Private method 'map(ObjIntFunction<T>)' is never used">map</warning>(ObjIntFunction<T> mapper) { + System.out.println(mapper); + return null; + } +} + +interface IntUnaryOperator { + public int applyAsInt(int operand); +} + +interface ObjIntFunction<T> { + public T apply(int i); +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/FunctionalInterfaceAnnotation.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/FunctionalInterfaceAnnotation.java new file mode 100644 index 000000000000..05b2585c8405 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/FunctionalInterfaceAnnotation.java @@ -0,0 +1,5 @@ +<error descr="Multiple non-overriding abstract methods found">@FunctionalInterface</error> +interface Test { + void foo(); + void bar(); +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompleteSubst.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompleteSubst.java index 9085c69489d3..366bea30534d 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompleteSubst.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompleteSubst.java @@ -48,7 +48,7 @@ class LambdaTest2<TypeParam> { U map(T t); } - public <U> LambdaTest<U> map(final Mapper<? super TypeParam, ? extends U> mapper) { + public <U> LambdaTest2<U> map(final Mapper<? super TypeParam, ? extends U> mapper) { return null; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IntersectionTypeInCast.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IntersectionTypeInCast.java new file mode 100644 index 000000000000..49a261c8b8de --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IntersectionTypeInCast.java @@ -0,0 +1,8 @@ +import java.io.Serializable; +import java.util.*; + +class Test { + public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> foo() { + return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/UnhandledExceptions.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/UnhandledExceptions.java new file mode 100644 index 000000000000..077940408e56 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/UnhandledExceptions.java @@ -0,0 +1,19 @@ +public class ExTest { + public static void maybeThrow(String data) throws Ex { + throw new Ex(data); + } + + { + Block<String> b = (t) -> <error descr="Unhandled exception: ExTest.Ex">ExTest.maybeThrow(t)</error>; + } + + + private static class Ex extends Throwable { + public Ex(String s) { + } + } +} + +interface Block<T> { + public void accept(T t); +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DefaultMethodVisibility.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodVisibility.java index 4a2c0eeb4801..4a2c0eeb4801 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DefaultMethodVisibility.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodVisibility.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/ExtensionMethodSyntax.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/ExtensionMethodSyntax.java index a5e0917301b6..a5e0917301b6 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/ExtensionMethodSyntax.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/ExtensionMethodSyntax.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/ExtensionMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/ExtensionMethods.java index a7fcb99947c1..44a2a1aaf39f 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/ExtensionMethods.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/ExtensionMethods.java @@ -50,7 +50,7 @@ class D { } interface IllegalMods { - <error descr="Illegal combination of modifiers: 'static' and 'abstract'">static</error> void m1(); + <error descr="Static methods in interfaces should have a body">static void m1()</error>; <error descr="Illegal combination of modifiers: 'static' and 'default'">static</error> void m2() default { } <error descr="Illegal combination of modifiers: 'static' and 'default'">static</error> <error descr="Illegal combination of modifiers: 'default' and 'static'">default</error> void m3() { } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/InheritUnrelatedDefaults.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/InheritUnrelatedDefaults.java new file mode 100644 index 000000000000..bbcf8b47d745 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/InheritUnrelatedDefaults.java @@ -0,0 +1,3 @@ +interface B { default void foo() {} } +interface C { default void foo() {} } +class <error descr="D inherits unrelated defaults for foo() from types B and C">D</error> implements B, C {} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/NotInheritFromUnrelatedDefault.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/NotInheritFromUnrelatedDefault.java new file mode 100644 index 000000000000..cfc1ee7abec4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/NotInheritFromUnrelatedDefault.java @@ -0,0 +1,15 @@ +interface FirstParent { + + default int doSomething() { + return 1; + } +} + +interface SecondParent { + + int doSomething(); +} + +class <error descr="Class 'SecondParent' must either be declared abstract or implement abstract method 'doSomething()' in 'SecondParent'">FirstSon</error> implements FirstParent, SecondParent {} + +<error descr="Class 'SecondSon' must either be declared abstract or implement abstract method 'doSomething()' in 'SecondParent'">class SecondSon implements SecondParent, FirstParent</error> {}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/staticMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/staticMethod.java new file mode 100644 index 000000000000..d1a1f41c7bc0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/staticMethod.java @@ -0,0 +1,4 @@ +interface Foo { + public static void bar1() {} + public <error descr="Illegal combination of modifiers: 'abstract' and 'static'">abstract</error> static void bar2() {} +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/CapturedWildcards.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/CapturedWildcards.java new file mode 100644 index 000000000000..269b075c4d84 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/CapturedWildcards.java @@ -0,0 +1,14 @@ +public class Main { + public static <T> void make(final Consumer<? super T> consumer) { + Sink<T> accept = (Sink<T>) consumer::accept; + Consumer<T> accept1 = (Consumer<T>)consumer::accept; + } +} + +interface Sink<T> extends Consumer<T> { + +} + +interface Consumer<T> { + public void accept(T t); +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ConstructorNonAbstractAbstractExpected.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ConstructorNonAbstractAbstractExpected.java new file mode 100644 index 000000000000..86d8bea66f7d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/ConstructorNonAbstractAbstractExpected.java @@ -0,0 +1,23 @@ +import java.util.ArrayList; +import java.util.List; + +public class IDEA99970 { + public static <T, C> Collector<T, C> toCollection(Supplier<C> collectionFactory) { + return null; + } + + public static <T> Collector<T, List<T>> toList() { + return toCollection(ArrayList<T>::new); + } + + public static <T> Collector<T, List<T>> toList1() { + return toCollection(ArrayList<T>::new); + } + +} + +interface Supplier<T> { + public T get(); +} + +interface Collector<T, R> {}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/IntersectionTypeInCast.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/IntersectionTypeInCast.java new file mode 100644 index 000000000000..f3c5e504f1e0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/IntersectionTypeInCast.java @@ -0,0 +1,6 @@ +import java.io.Serializable; +class Test { + { + Runnable r = (Runnable & Serializable)Test::new; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/UnhandledExceptions.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/UnhandledExceptions.java new file mode 100644 index 000000000000..a03154d9ecf4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/UnhandledExceptions.java @@ -0,0 +1,19 @@ +public class ExTest { + public static void maybeThrow(String data) throws Ex { + throw new Ex(data); + } + + { + Block<String> b = <error descr="Unhandled exception: ExTest.Ex">ExTest::maybeThrow</error>; + } + + + private static class Ex extends Throwable { + public Ex(String s) { + } + } +} + +interface Block<T> { + public void accept(T t); +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParamsWithWildcards.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParamsWithWildcards.java new file mode 100644 index 000000000000..0bbcdd54dd92 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/FormalParamsWithWildcards.java @@ -0,0 +1,9 @@ +class Test { + public interface I<K, V> { + public V put(K k); + } + + { + final I<? super Long, CharSequence> i = (Number n) -> n.toString(); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/Raw.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/Raw.java index e99747fa6169..eeaa80410bb6 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/Raw.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/Raw.java @@ -1,7 +1,7 @@ class Test { { - <error descr="Incompatible types. Found: '<lambda expression>', required: 'java.lang.Comparable'">Comparable c = (String o)->{ + Comparable c = (<error descr="Incompatible parameter types in lambda expression">String o</error>)->{ return 0; - };</error> + }; } }
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/beforeQualifiedNew.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/beforeQualifiedNew.java new file mode 100644 index 000000000000..516a79faae83 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/beforeQualifiedNew.java @@ -0,0 +1,6 @@ +// "Create Class 'ArrayList'" "false" +public class Test { + public static void main() { + q.new <caret>ArrayList(); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeQualifiedNew1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeQualifiedNew1.java new file mode 100644 index 000000000000..ce4542d9e4f9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeQualifiedNew1.java @@ -0,0 +1,6 @@ +// "Create Inner Class 'ArrayList'" "false" +public class Test { + public static void main() { + q.new <caret>ArrayList(); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeQualifiedNew2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeQualifiedNew2.java new file mode 100644 index 000000000000..6fa79f02d8d9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew/beforeQualifiedNew2.java @@ -0,0 +1,9 @@ +// "Create Inner Class 'ArrayList'" "false" +public class Test { + public static void main() { + Inner q = new Inner(); + q.new <caret>ArrayList(); + } + + static class Inner { } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createLocalVarFromInstanceof/afterInSimpleMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createLocalVarFromInstanceof/afterInSimpleMethod.java new file mode 100644 index 000000000000..f4477b22bed5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createLocalVarFromInstanceof/afterInSimpleMethod.java @@ -0,0 +1,11 @@ +// "Insert '(NodeInfo)parent' declaration" "true" +public abstract class A { + public void getNodeElements(Object parent) { + if (!(parent instanceof NodeInfo)) return; + NodeInfo nodeInfo = (NodeInfo) parent; + <caret> + } + + private static class NodeInfo { + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createLocalVarFromInstanceof/beforeInSimpleMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createLocalVarFromInstanceof/beforeInSimpleMethod.java new file mode 100644 index 000000000000..8a78a53124e2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createLocalVarFromInstanceof/beforeInSimpleMethod.java @@ -0,0 +1,9 @@ +// "Insert '(NodeInfo)parent' declaration" "true" +public abstract class A { + public void getNodeElements(Object parent) { + if (!(parent instanceof <caret>NodeInfo)) return; + } + + private static class NodeInfo { + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterAmbiguosResult.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterAmbiguosResult.java new file mode 100644 index 000000000000..c6614e06a7fb --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterAmbiguosResult.java @@ -0,0 +1,21 @@ +// "Replace lambda with method reference" "true" +import java.util.*; +class IDEA100385 { + void foo(N<Double> n, List<Double> l){ + n.forEach((DoubleConsumer) l::add); + } + static interface N<E> { + default void forEach(DoubleConsumer consumer) { + } + void forEach(Consumer<? super E> consumer); + } + + interface DoubleConsumer { + void _(double d); + } + + interface Consumer<T> { + public void accept(T t); + } + +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterLocalClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterLocalClass.java new file mode 100644 index 000000000000..27a9470f21dd --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterLocalClass.java @@ -0,0 +1,37 @@ +// "Replace lambda with method reference" "true" +public class IDEA100452 { + public static <T> MatchOp<T> match(MatchOp.MatchKind matchKind) { + class MatchSink extends BooleanTerminalSink<T> { + + private MatchSink() { + super(matchKind); + } + + @Override + public void accept(T t) { + } + } + + Supplier<BooleanTerminalSink<T>> s = MatchSink::new; + return new MatchOp<>(1, matchKind, s); + } + + static abstract class BooleanTerminalSink<T> { + public BooleanTerminalSink(MatchOp.MatchKind matchKind) { + + } + + public abstract void accept(T t); + } + static interface Supplier<T> { + public T get(); + } + + static class MatchOp<H> { + public MatchOp(int i, MatchKind matchKind, Supplier<BooleanTerminalSink<H>> s) { + //To change body of created methods use File | Settings | File Templates. + } + + static enum MatchKind {} + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAmbiguosResult.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAmbiguosResult.java new file mode 100644 index 000000000000..077b9e6c91f2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAmbiguosResult.java @@ -0,0 +1,23 @@ +// "Replace lambda with method reference" "true" +import java.util.*; +class IDEA100385 { + void foo(N<Double> n, List<Double> l){ + n.forEach((double e) -> { + l.ad<caret>d(e); + }); + } + static interface N<E> { + default void forEach(DoubleConsumer consumer) { + } + void forEach(Consumer<? super E> consumer); + } + + interface DoubleConsumer { + void _(double d); + } + + interface Consumer<T> { + public void accept(T t); + } + +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeLocalClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeLocalClass.java new file mode 100644 index 000000000000..9dfd3b42f1b3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeLocalClass.java @@ -0,0 +1,37 @@ +// "Replace lambda with method reference" "true" +public class IDEA100452 { + public static <T> MatchOp<T> match(MatchOp.MatchKind matchKind) { + class MatchSink extends BooleanTerminalSink<T> { + + private MatchSink() { + super(matchKind); + } + + @Override + public void accept(T t) { + } + } + + Supplier<BooleanTerminalSink<T>> s = () -> new Match<caret>Sink(); + return new MatchOp<>(1, matchKind, s); + } + + static abstract class BooleanTerminalSink<T> { + public BooleanTerminalSink(MatchOp.MatchKind matchKind) { + + } + + public abstract void accept(T t); + } + static interface Supplier<T> { + public T get(); + } + + static class MatchOp<H> { + public MatchOp(int i, MatchKind matchKind, Supplier<BooleanTerminalSink<H>> s) { + //To change body of created methods use File | Settings | File Templates. + } + + static enum MatchKind {} + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/afterChain.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/afterChain.java new file mode 100644 index 000000000000..7d3370d33743 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/afterChain.java @@ -0,0 +1,10 @@ +// "Replace with 'integer != null ?:'" "true" + +import java.lang.Integer; + +class A{ + void test(){ + Integer integer = null; + int i = integer != null ? integer.toString().length() : <selection>0</selection>; + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/beforeChain.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/beforeChain.java new file mode 100644 index 000000000000..4728847e397b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/beforeChain.java @@ -0,0 +1,10 @@ +// "Replace with 'integer != null ?:'" "true" + +import java.lang.Integer; + +class A{ + void test(){ + Integer integer = null; + int i = in<caret>teger.toString().length(); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/afterLambdaCodeBlock.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/afterLambdaCodeBlock.java new file mode 100644 index 000000000000..67eeb7469d52 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/afterLambdaCodeBlock.java @@ -0,0 +1,26 @@ +// "Surround with try/catch" "true" +public class ExTest { + public static void maybeThrow(String data) throws Ex { + throw new Ex(data); + } + + { + Block<String> b = (t) -> { + try { + return ExTest.maybeThrow(t); + } catch (Ex ex) { + <selection>ex.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.</selection> + } + }; + } + + + private static class Ex extends Throwable { + public Ex(String s) { + } + } +} + +interface Block<T> { + public void accept(T t); +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/beforeLambdaCodeBlock.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/beforeLambdaCodeBlock.java new file mode 100644 index 000000000000..1b296d021490 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/beforeLambdaCodeBlock.java @@ -0,0 +1,20 @@ +// "Surround with try/catch" "true" +public class ExTest { + public static void maybeThrow(String data) throws Ex { + throw new Ex(data); + } + + { + Block<String> b = (t) -> { return ExTest.may<caret>beThrow(t);}; + } + + + private static class Ex extends Throwable { + public Ex(String s) { + } + } +} + +interface Block<T> { + public void accept(T t); +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/beforeLambdaExpr.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/beforeLambdaExpr.java new file mode 100644 index 000000000000..2cb6adb41d38 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/beforeLambdaExpr.java @@ -0,0 +1,20 @@ +// "Surround with try/catch" "false" +public class ExTest { + public static void maybeThrow(String data) throws Ex { + throw new Ex(data); + } + + { + Block<String> b = (t) -> ExTest.may<caret>beThrow(t); + } + + + private static class Ex extends Throwable { + public Ex(String s) { + } + } +} + +interface Block<T> { + public void accept(T t); +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/beforeMethodRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/beforeMethodRef.java new file mode 100644 index 000000000000..80cc540bed71 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithTry/beforeMethodRef.java @@ -0,0 +1,20 @@ +// "Surround with try/catch" "false" +public class ExTest { + public static void maybeThrow(String data) throws Ex { + throw new Ex(data); + } + + { + Block<String> b = ExTest::may<caret>beThrow(t); + } + + + private static class Ex extends Throwable { + public Ex(String s) { + } + } +} + +interface Block<T> { + public void accept(T t); +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/documentation/inherit.gif b/java/java-tests/testData/codeInsight/documentation/inherit.gif Binary files differnew file mode 100644 index 000000000000..c814867a13de --- /dev/null +++ b/java/java-tests/testData/codeInsight/documentation/inherit.gif diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis1.java b/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis1.java new file mode 100644 index 000000000000..4584077665e2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis1.java @@ -0,0 +1,11 @@ +// "Invert If Condition" "true" +class Inversion { + public void context(boolean a, boolean b, boolean c) { + if ((!a || !b) && !c) { + System.out.println(1); + } + else { + System.out.println(0); + } + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis2.java b/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis2.java new file mode 100644 index 000000000000..fd19babc6d64 --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis2.java @@ -0,0 +1,11 @@ +// "Invert If Condition" "true" +class Inversion { + public void context(boolean a, boolean b, boolean c) { + if (!a || !b || !c) { + System.out.println(1); + } + else { + System.out.println(0); + } + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis3.java b/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis3.java new file mode 100644 index 000000000000..ca8ef27512f5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis3.java @@ -0,0 +1,11 @@ +// "Invert If Condition" "true" +class Inversion { + public void context(boolean a, boolean b, boolean c) { + if ((!a && !b) || !c) { + System.out.println(1); + } + else { + System.out.println(0); + } + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis1.java b/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis1.java new file mode 100644 index 000000000000..910ff076934f --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis1.java @@ -0,0 +1,10 @@ +// "Invert If Condition" "true" +class Inversion { + public void context(boolean a, boolean b, boolean c) { + if (a &<caret>& b || c) { + System.out.println(0); + } else { + System.out.println(1); + } + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis2.java b/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis2.java new file mode 100644 index 000000000000..4aab06463a17 --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis2.java @@ -0,0 +1,10 @@ +// "Invert If Condition" "true" +class Inversion { + public void context(boolean a, boolean b, boolean c) { + if (a &<caret>& b && c) { + System.out.println(0); + } else { + System.out.println(1); + } + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis3.java b/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis3.java new file mode 100644 index 000000000000..256ef0b2efc3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis3.java @@ -0,0 +1,10 @@ +// "Invert If Condition" "true" +class Inversion { + public void context(boolean a, boolean b, boolean c) { + if ((a |<caret>| b) && c) { + System.out.println(0); + } else { + System.out.println(1); + } + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/initializerWithReference.html b/java/java-tests/testData/codeInsight/javadocIG/initializerWithReference.html new file mode 100644 index 000000000000..f4ba3cbff9d1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/initializerWithReference.html @@ -0,0 +1 @@ +<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b><a href="psi_element://Test"><code>Test</code></a></b></small><PRE>public int <b>field = anotherField</b></PRE></body></html>
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/initializerWithReference.java b/java/java-tests/testData/codeInsight/javadocIG/initializerWithReference.java new file mode 100644 index 000000000000..39a7384fdbb1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/initializerWithReference.java @@ -0,0 +1,4 @@ +class Test { + public int field = anotherField; + public static int anotherField = 1; +}
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/splitIfAction/afterWithoutSpaces.java b/java/java-tests/testData/codeInsight/splitIfAction/afterWithoutSpaces.java new file mode 100644 index 000000000000..f776d7d19b7d --- /dev/null +++ b/java/java-tests/testData/codeInsight/splitIfAction/afterWithoutSpaces.java @@ -0,0 +1,8 @@ +public class SplitCondition { + private static void appendString(StringBuilder builder, boolean condition) { + if (condition) { + if (builder.length() > 0) { + } + } + } +} diff --git a/java/java-tests/testData/codeInsight/splitIfAction/beforeWithoutSpaces.java b/java/java-tests/testData/codeInsight/splitIfAction/beforeWithoutSpaces.java new file mode 100644 index 000000000000..b573566020ce --- /dev/null +++ b/java/java-tests/testData/codeInsight/splitIfAction/beforeWithoutSpaces.java @@ -0,0 +1,6 @@ +public class SplitCondition { + private static void appendString(StringBuilder builder, boolean condition) { + if (condition&<caret>&builder.length() > 0) { + } + } +} diff --git a/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass.log b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass.log new file mode 100644 index 000000000000..39635f36edb8 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass.log @@ -0,0 +1,10 @@ +Compiling files: +src2/pkg/Constants.java +End of files +Cleaning output files: +out/production/addDuplicateClass/pkg/Constants.class +End of files +Compiling files: +src/pkg/Constants.java +src2/pkg/Constants.java +End of files diff --git a/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/.idea/misc.xml b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/.idea/misc.xml new file mode 100644 index 000000000000..9a249d2930c5 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/.idea/misc.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="EntryPointsManager"> + <entry_points version="2.0" /> + </component> + <component name="ProjectResources"> + <default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype> + </component> + <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="IDEA jdk" project-jdk-type="JavaSDK"> + <output url="file://$PROJECT_DIR$/out" /> + </component> +</project> + diff --git a/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/.idea/modules.xml b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/.idea/modules.xml new file mode 100644 index 000000000000..6c4ca79986a8 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/.idea/modules.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/addDuplicateClass.iml" filepath="$PROJECT_DIR$/addDuplicateClass.iml" /> + </modules> + </component> +</project> + diff --git a/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/addDuplicateClass.iml b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/addDuplicateClass.iml new file mode 100644 index 000000000000..119c6ef0a879 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/addDuplicateClass.iml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/src2" isTestSource="false" /> + </content> + <orderEntry type="jdk" jdkName="IDEA jdk" jdkType="JavaSDK" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="module" module-name="common" /> + </component> +</module> + diff --git a/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/src/pkg/Client.java b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/src/pkg/Client.java new file mode 100644 index 000000000000..8d9b52bd6ff2 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/src/pkg/Client.java @@ -0,0 +1,6 @@ +package pkg; +public class Client { + public static void main(String[] args) { + System.out.println(Constants.NUMBER); + } +} diff --git a/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/src/pkg/Constants.java b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/src/pkg/Constants.java new file mode 100644 index 000000000000..edc79841dffe --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/src/pkg/Constants.java @@ -0,0 +1,4 @@ +package pkg; +public class Constants { + public static final Integer NUMBER = new Integer(10); +} diff --git a/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/src2/pkg/Constants.java.new b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/src2/pkg/Constants.java.new new file mode 100644 index 000000000000..0f9f6ffd7960 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/addDuplicateClass/src2/pkg/Constants.java.new @@ -0,0 +1,3 @@ +package pkg; +public class Constants { +} diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod.log b/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod.log new file mode 100644 index 000000000000..ea3129552780 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod.log @@ -0,0 +1,12 @@ +Cleaning output files: +out/production/RemoveMoreAccessibleMethod/x/Concrete.class +End of files +Compiling files: +src/x/Concrete.java +End of files +Cleaning output files: +out/production/RemoveMoreAccessibleMethod/x/y/Client.class +End of files +Compiling files: +src/x/y/Client.java +End of files diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod/src/x/Abstract.java b/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod/src/x/Abstract.java new file mode 100644 index 000000000000..ab43a5b2ae00 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod/src/x/Abstract.java @@ -0,0 +1,6 @@ +package x; + +public class Abstract { + protected void method(int a) { + } +} diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod/src/x/Concrete.java b/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod/src/x/Concrete.java new file mode 100644 index 000000000000..8a992bb4ca8d --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod/src/x/Concrete.java @@ -0,0 +1,7 @@ +package x; + +public class Concrete extends Abstract{ + @Override + public void method(int a) { + } +} diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod/src/x/Concrete.java.new b/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod/src/x/Concrete.java.new new file mode 100644 index 000000000000..1502b7ddf13b --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod/src/x/Concrete.java.new @@ -0,0 +1,4 @@ +package x; + +public class Concrete extends Abstract{ +} diff --git a/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod/src/x/y/Client.java b/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod/src/x/y/Client.java new file mode 100644 index 000000000000..6a759deba6bc --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/membersChange/removeMoreAccessibleMethod/src/x/y/Client.java @@ -0,0 +1,11 @@ +package x.y; + +import x.*; + +public class Client { + private static Concrete concrete; + + public static void main(String[] args) { + concrete.method(10); + } +} diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ChainedFinalFieldAccessorsDfa.java b/java/java-tests/testData/inspection/dataFlow/fixture/ChainedFinalFieldAccessorsDfa.java index 8cf8bbdd8c2f..12c6fb1ad9bf 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/ChainedFinalFieldAccessorsDfa.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ChainedFinalFieldAccessorsDfa.java @@ -12,28 +12,28 @@ public class BrokenAlignment { data = new Data(null, <warning descr="Passing 'null' argument to non annotated parameter">null</warning>); System.out.println(<warning descr="Method invocation 'data.getText().hashCode()' may produce 'java.lang.NullPointerException'">data.getText().hashCode()</warning>); - if (data.inner() != null) { - System.out.println(data.inner().hashCode()); - System.out.println(<warning descr="Method invocation 'data.inner().getText().hashCode()' may produce 'java.lang.NullPointerException'">data.inner().getText().hashCode()</warning>); - if (data.inner() != null) { - System.out.println(data.inner().hashCode()); + if (data.getInner() != null) { + System.out.println(data.getInner().hashCode()); + System.out.println(<warning descr="Method invocation 'data.getInner().getText().hashCode()' may produce 'java.lang.NullPointerException'">data.getInner().getText().hashCode()</warning>); + if (data.getInner() != null) { + System.out.println(data.getInner().hashCode()); } data = new Data(null, <warning descr="Passing 'null' argument to non annotated parameter">null</warning>); - System.out.println(<warning descr="Method invocation 'data.inner().hashCode()' may produce 'java.lang.NullPointerException'">data.inner().hashCode()</warning>); + System.out.println(<warning descr="Method invocation 'data.getInner().hashCode()' may produce 'java.lang.NullPointerException'">data.getInner().hashCode()</warning>); } } void main2(Data data) { - if (data.inner() != null && data.inner().getText() != null) { - System.out.println(data.inner().hashCode()); - System.out.println(data.inner().getText().hashCode()); + if (data.getInner() != null && data.getInner().getText() != null) { + System.out.println(data.getInner().hashCode()); + System.out.println(data.getInner().getText().hashCode()); } } void main3(Data data) { - if (data.innerOverridden() != null) { - System.out.println(data.innerOverridden().hashCode()); + if (data.getInnerOverridden() != null) { + System.out.println(data.getInnerOverridden().hashCode()); } if (data.something() != null) { System.out.println(<warning descr="Method invocation 'data.something().hashCode()' may produce 'java.lang.NullPointerException'">data.something().hashCode()</warning>); @@ -55,12 +55,12 @@ public class BrokenAlignment { } @Nullable - public Data inner() { + public Data getInner() { return inner; } @Nullable - public Data innerOverridden() { + public Data getInnerOverridden() { return inner; } @@ -77,8 +77,8 @@ public class BrokenAlignment { @Nullable @Override - public Data innerOverridden() { - return super.innerOverridden(); + public Data getInnerOverridden() { + return super.getInnerOverridden(); } } }
\ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/EffectivelyUnqualified.java b/java/java-tests/testData/inspection/dataFlow/fixture/EffectivelyUnqualified.java new file mode 100644 index 000000000000..86ed56676e26 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/EffectivelyUnqualified.java @@ -0,0 +1,12 @@ +abstract class Foo { + protected String bar; +} + +class FF extends Foo { + class FFI extends Foo { + void f() { + if (this.bar == FF.this.bar); + if (<warning descr="Condition 'this.bar == FFI.this.bar' is always 'true'">this.bar == FFI.this.bar</warning>); + } + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/EqualsHasNoSideEffects.java b/java/java-tests/testData/inspection/dataFlow/fixture/EqualsHasNoSideEffects.java new file mode 100644 index 000000000000..20d33e187598 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/EqualsHasNoSideEffects.java @@ -0,0 +1,22 @@ +class DefaultObjectIdentifier { + String user; + String requestorClass; + public boolean equals(Object otherObject) { + if (otherObject == null || !(otherObject instanceof DefaultObjectIdentifier)) + return false; + else { + DefaultObjectIdentifier identifier = (DefaultObjectIdentifier) otherObject; + if (user == null && identifier.user != null) + return false; + else if (requestorClass == null && identifier.requestorClass != null) + return false; + else if (((user == null && <warning descr="Condition 'identifier.user == null' is always 'true' when reached">identifier.user == null</warning>) + || (this.user.equals(identifier.user))) + && + ((requestorClass == null && <warning descr="Condition 'identifier.requestorClass == null' is always 'true' when reached">identifier.requestorClass == null</warning>) + || this.requestorClass.equals(identifier.requestorClass))) + return true; + else + return false; + } + }}
\ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/MutableNotAnnotatedFieldsTreatment.java b/java/java-tests/testData/inspection/dataFlow/fixture/MutableNotAnnotatedFieldsTreatment.java index a7c67e05861f..c542ba8fc158 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/MutableNotAnnotatedFieldsTreatment.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/MutableNotAnnotatedFieldsTreatment.java @@ -32,11 +32,11 @@ class Foo { System.out.println(data.hashCode()); } - void dontWarnWhenDoubleChecked(Foo f) { + void warnWhenDoubleChecked(Foo f) { if (f.data == null) { return; } - if (f.data == null) { + if (<warning descr="Condition 'f.data == null' is always 'false'">f.data == null</warning>) { return; } System.out.println(f.data.hashCode()); @@ -53,13 +53,13 @@ class Foo { } System.out.println(data.hashCode()); } - - void dontWarnWhenDoubleChecked_This_WithMethodCall() { + + void warnWhenDoubleChecked_This_WithMethodCall() { if (data == null) { return; } System.out.println(data.hashCode()); - if (data == null) { + if (<warning descr="Condition 'data == null' is always 'false'">data == null</warning>) { return; } System.out.println(data.hashCode()); diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/MutableNullableFieldsTreatment.java b/java/java-tests/testData/inspection/dataFlow/fixture/MutableNullableFieldsTreatment.java index ee2b1813b4d2..107d11f2bd75 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/MutableNullableFieldsTreatment.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/MutableNullableFieldsTreatment.java @@ -34,11 +34,11 @@ class Foo { System.out.println(data.hashCode()); } - void dontWarnWhenDoubleChecked(Foo f) { + void warnWhenDoubleChecked(Foo f) { if (f.data == null) { return; } - if (f.data == null) { + if (<warning descr="Condition 'f.data == null' is always 'false'">f.data == null</warning>) { return; } System.out.println(f.data.hashCode()); @@ -56,12 +56,12 @@ class Foo { System.out.println(data.hashCode()); } - void dontWarnWhenDoubleChecked_This_WithMethodCall() { + void warnWhenDoubleChecked_This_WithMethodCall() { if (data == null) { return; } System.out.println(data.hashCode()); - if (data == null) { + if (<warning descr="Condition 'data == null' is always 'false'">data == null</warning>) { return; } System.out.println(data.hashCode()); diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/OmnipresentExceptions.java b/java/java-tests/testData/inspection/dataFlow/fixture/OmnipresentExceptions.java new file mode 100644 index 000000000000..185c8ef269b1 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/OmnipresentExceptions.java @@ -0,0 +1,30 @@ +class Test { + Object m1(String[] args) throws Exception { + try { + return <warning descr="'null' is returned by the method which isn't declared as @Nullable">null</warning>; + } + catch (Throwable t) { + if (t instanceof Error) { + System.err.println("1"); + } + if (!(t instanceof RuntimeException)) { + System.err.println("2"); + } + return null; + } + } + + void m2(String[] args) throws Exception { + try { + System.out.println(); + } + catch (Throwable t) { + if (t instanceof Error) { + System.err.println("1"); + } + if (!(t instanceof RuntimeException)) { + System.err.println("2"); + } + } + } +} diff --git a/java/java-tests/testData/inspection/dataFlow/TryWithResourcesInstanceOf.java b/java/java-tests/testData/inspection/dataFlow/fixture/TryWithResourcesInstanceOf.java index f2ac4a8f3ba4..f2ac4a8f3ba4 100644 --- a/java/java-tests/testData/inspection/dataFlow/TryWithResourcesInstanceOf.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/TryWithResourcesInstanceOf.java diff --git a/java/java-tests/testData/inspection/dataFlow/TryWithResourcesNullability.java b/java/java-tests/testData/inspection/dataFlow/fixture/TryWithResourcesNullability.java index 80435df3b452..80435df3b452 100644 --- a/java/java-tests/testData/inspection/dataFlow/TryWithResourcesNullability.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/TryWithResourcesNullability.java diff --git a/java/java-tests/testData/inspection/sillyAssignment/multiple/src/Test.java b/java/java-tests/testData/inspection/sillyAssignment/multiple/src/Test.java index 0b3feb5b6203..2ddf2b6d6d10 100644 --- a/java/java-tests/testData/inspection/sillyAssignment/multiple/src/Test.java +++ b/java/java-tests/testData/inspection/sillyAssignment/multiple/src/Test.java @@ -20,5 +20,18 @@ public class Test extends Super { } class Super { int h; + int bar; } + +class Outer extends Super { + class Inner extends Super { + void f() { + this.bar = Outer.this.bar; + bar = Outer.this.bar; + this.bar = Outer.super.bar; + bar = Outer.super.bar; + super.bar = Outer.super.bar; + } + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/genericWithTwoParameters/after/Client.java b/java/java-tests/testData/refactoring/introduceVariable/genericWithTwoParameters/after/Client.java index 4760e5ef0e09..38d94b3a880b 100644 --- a/java/java-tests/testData/refactoring/introduceVariable/genericWithTwoParameters/after/Client.java +++ b/java/java-tests/testData/refactoring/introduceVariable/genericWithTwoParameters/after/Client.java @@ -2,6 +2,6 @@ import util.Pair; class Client { void method() { - Pair<String,Pair<Integer,Boolean>> p = PairProvider.getPair(); + Pair<String, Pair<Integer,Boolean>> p = PairProvider.getPair(); } }
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/renameLocal/RenameToFieldNameInStaticContext.java b/java/java-tests/testData/refactoring/renameLocal/RenameToFieldNameInStaticContext.java new file mode 100644 index 000000000000..7fc1574ce187 --- /dev/null +++ b/java/java-tests/testData/refactoring/renameLocal/RenameToFieldNameInStaticContext.java @@ -0,0 +1,7 @@ +class Test { + String myFoo; + static { + String f<caret>oo = ""; + System.out.println(myFoo); + } +}
\ No newline at end of file diff --git a/java/java-tests/testData/refactoring/renameLocal/RenameToFieldNameInStaticContext_after.java b/java/java-tests/testData/refactoring/renameLocal/RenameToFieldNameInStaticContext_after.java new file mode 100644 index 000000000000..6d3f3b994262 --- /dev/null +++ b/java/java-tests/testData/refactoring/renameLocal/RenameToFieldNameInStaticContext_after.java @@ -0,0 +1,7 @@ +class Test { + String myFoo; + static { + String myFoo = ""; + System.out.println(myFoo); + } +}
\ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/GlobalMemberNameCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/GlobalMemberNameCompletionTest.groovy index 1fc4145095c2..c70c166a19b0 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/GlobalMemberNameCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/GlobalMemberNameCompletionTest.groovy @@ -197,6 +197,44 @@ class A { ''' } + public void "test static import before an identifier"() { + myFixture.addClass ''' +package test.t1; + +public enum DemoEnum +{ + XXONE, + TWO +}''' + doTest """ +import test.t1.DemoEnum; + +public class Demo { + + public static void doStuff(DemoEnum enumValue, String value) {} + public static void main(String[] args) + { + String val = "anyValue"; + doStuff(XXON<caret>val); + } +} +""", true, """ +import test.t1.DemoEnum; + +import static test.t1.DemoEnum.XXONE; + +public class Demo { + + public static void doStuff(DemoEnum enumValue, String value) {} + public static void main(String[] args) + { + String val = "anyValue"; + doStuff(XXONE<caret>val); + } +} +""" + } + private void doTest(String input, boolean importStatic, String output) { myFixture.configureByText("a.java", input) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy new file mode 100644 index 000000000000..d8a49bfd7cae --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HippieCompletionTest.groovy @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.completion + +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +/** + * @author peter + */ +class HippieCompletionTest extends LightCodeInsightFixtureTestCase { + + public void testDollars() { + myFixture.configureByText "a.txt", ''' +$some_long_variable_name = Obj::instance(); +$some_lon<caret> +''' + myFixture.performEditorAction("HippieCompletion") + myFixture.checkResult ''' +$some_long_variable_name = Obj::instance(); +$some_long_variable_name<caret> +''' + } + +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy index 904e83c41fe9..bc2a12897497 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -60,14 +60,14 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { } """) type('i') - assertContains("if", "iterable", "int") + assertContains("iterable", "if", "int") type('t') assertContains "iterable" assertEquals 'iterable', lookup.currentItem.lookupString type('er') - assertContains("iter", "iterable") + assertContains "iterable", "iter" assertEquals 'iterable', lookup.currentItem.lookupString assert lookup.focused @@ -76,7 +76,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { } def assertContains(String... items) { - assert myFixture.lookupElementStrings.containsAll(items as List) + myFixture.assertPreferredCompletionItems(0, items) } public void testRecalculateItemsOnBackspace() { @@ -89,7 +89,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { } """) type "r" - assertContains "iter", "iterable" + assertContains "iterable", "iter" type '\b' assertContains "iterable" @@ -104,7 +104,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { assertContains "iterable" type "r" - assertContains "iter", "iterable" + assertContains "iterable", "iter" } public void testExplicitSelectionShouldSurvive() { @@ -124,8 +124,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { assertEquals 'iterable2', lookup.currentItem.lookupString type "r" - assertContains "iter", "iterable", 'iterable2' - assertEquals 'iterable2', lookup.currentItem.lookupString + myFixture.assertPreferredCompletionItems 2, "iterable", "iter", 'iterable2' } @@ -146,8 +145,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { assertEquals 'iterable2', lookup.currentItem.lookupString type "r" - assertContains "iter", "iterable", 'iterable2' - assertEquals 'iterable2', lookup.currentItem.lookupString + myFixture.assertPreferredCompletionItems 2, "iterable", "iter", 'iterable2' } @@ -554,7 +552,7 @@ public interface Test { """) type('i') def offset = myFixture.editor.caretModel.offset - assertContains "if", "iterable", "int" + assertContains "iterable", "if", "int" edt { myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT) } assert myFixture.editor.caretModel.offset == offset + 1 @@ -569,7 +567,7 @@ public interface Test { joinAutopopup() joinCompletion() assert !lookup.calculating - assertContains "if", "iterable", "int" + assertContains "iterable", "if", "int" assertEquals 'iterable', lookup.currentItem.lookupString edt { myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT) } @@ -656,26 +654,6 @@ public interface Test { } } - public void testTemplateSelectionByComma() { - myFixture.configureByText("a.java", """ -class Foo { - int itea = 2; - int itera = 2; - - { - it<caret> - } -} -""") - type 'e' - assertContains "itea", "itera" - type 'r' - assertContains "iter", "itera" - type ',' - assert !lookup - assert myFixture.editor.document.text.contains('itera,') - } - public void testTemplateSelectionBySpace() { myFixture.configureByText("a.java", """ class Foo { @@ -959,7 +937,7 @@ class Foo { } type('_') - assertContains 'x__foo', 'x__goo' + myFixture.assertPreferredCompletionItems 1, 'x__foo', 'x__goo' edt { assert goo == TargetElementUtil.instance.findTargetElement(myFixture.editor, TargetElementUtil.LOOKUP_ITEM_ACCEPTED) myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP) @@ -1076,14 +1054,6 @@ public class UTest { return editor } - public void _testCharSelectionUndo() { - myFixture.configureByText "a.java", "class Foo {{ <caret> }}" - def editor = openEditorForUndo(); - type('ArrStoExce.') - edt { UndoManager.getInstance(project).undo(editor) } - assert myFixture.editor.document.text.contains('ArrStoExce.') - } - public void testAutopopupTypingUndo() { myFixture.configureByText "a.java", "class Foo {{ <caret> }}" def editor = openEditorForUndo(); @@ -1288,7 +1258,14 @@ class Foo { } @Override + protected void setUp() { + super.setUp() + CodeInsightSettings.instance.SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS = true + } + + @Override protected void tearDown() { + CodeInsightSettings.instance.SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS = false CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.FIRST_LETTER super.tearDown() } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.java index 1f16310242b1..3c17cc882e85 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.java @@ -74,7 +74,7 @@ public class JavadocCompletionTest extends LightFixtureCompletionTestCase { public void testSee0() throws Exception { configureByFile("See0.java"); - assertStringItems("foo", "clone", "equals", "getClass", "hashCode", "notify", "notifyAll", "Object", "toString", "wait", "wait", "wait", "finalize", "registerNatives"); + myFixture.assertPreferredCompletionItems(0, "foo", "clone", "equals", "hashCode"); } public void testSee1() throws Exception { @@ -198,6 +198,12 @@ public class JavadocCompletionTest extends LightFixtureCompletionTestCase { assertTrue(getLookupElementStrings().containsAll(Arrays.asList("io", "lang", "util"))); } + public void testQualifyClassReferenceInPackageStatement() throws Exception { + configureByFile(getTestName(false) + ".java"); + myFixture.type('\n'); + checkResultByFile(getTestName(false) + "_after.java"); + } + public void testCustomReferenceProvider() throws Exception { PsiReferenceRegistrarImpl registrar = (PsiReferenceRegistrarImpl) ReferenceProvidersRegistry.getInstance().getRegistrar(StdLanguages.JAVA); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java index c50a4b5de7cc..55b27122e5f8 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java @@ -109,11 +109,13 @@ public class KeywordCompletionTest extends LightCompletionTestCase { public void testReturnInTernary() throws Exception { doTest(1, "return"); } public void testFinalAfterParameterAnno() throws Exception { doTest(2, "final", "float", "class"); } public void testFinalAfterParameterAnno2() throws Exception { doTest(2, "final", "float", "class"); } + public void testFinalAfterCase() throws Exception { doTest(3, "final", "float", "class"); } public void testFinalInTryWithResources() throws Exception { doTest(1, "final", "float", "class"); } public void testClassInMethod() throws Exception { doTest(2, "class", "char"); } public void testIntInClassArray() throws Throwable { doTest(2, "int", "char", "final"); } public void testIntInClassArray2() throws Throwable { doTest(2, "int", "char", "final"); } public void testIntInClassArray3() throws Throwable { doTest(2, "int", "char", "final"); } + public void testArrayClass() throws Throwable { doTest(1, "class", "interface"); } public void testIntInGenerics() throws Throwable { doTest(2, "int", "char", "final"); } public void testIntInGenerics2() throws Throwable { doTest(2, "int", "char", "final"); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy index 81466459ec26..6b5607b47cc1 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy @@ -195,7 +195,7 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { public void testDeclaredMembersGoFirst() throws Exception { invokeCompletion(getTestName(false) + ".java"); - assertStringItems("fromThis", "overridden", "fromSuper", "equals", "getClass", "hashCode", "notify", "notifyAll", "toString", "wait", + assertStringItems("fromThis", "overridden", "fromSuper", "equals", "hashCode", "toString", "getClass", "notify", "notifyAll", "wait", "wait", "wait"); } @@ -314,6 +314,11 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { } } + public void testAlphaSortingStartMatchesFirst() { + UISettings.getInstance().SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY = true + checkPreferredItems 0, 'xxbar', 'xxfoo', 'xxgoo', 'barxx', 'fooxx', 'gooxx' + } + public void testSortSameNamedVariantsByProximity() { myFixture.addClass("public class Bar {}"); for (int i = 0; i < 10; i++) { @@ -465,7 +470,7 @@ import java.lang.annotation.Target; repeatCompletion 'b' myFixture.completeBasic(); - assertPreferredItems(0, '_boo2', '_foo2', 'return', '_boo1', '_foo1', '_goo1', '_goo2') + assertPreferredItems(0, 'return', '_boo2', '_foo2', '_boo1', '_foo1', '_goo1', '_goo2') myFixture.type('_'); assertPreferredItems(0, '_boo2', '_foo2', '_boo1', '_foo1', '_goo1', '_goo2') myFixture.type('g') @@ -544,4 +549,11 @@ import java.lang.annotation.Target; checkPreferredItems(0, 'vx') } + public void testLocalVarsOverStats() { + CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE; + checkPreferredItems 0, 'psiElement', 'PsiElement' + incUseCount lookup, 1 + assertPreferredItems 0, 'psiElement', 'PsiElement' + } + } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index 880e7b175c7a..0c7e3f1ce4bf 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -85,6 +85,20 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase { public void testSimpleVariable() throws Exception { doTest('\n') } + public void testTypeParameterItemPresentation() { + configure() + LookupElementPresentation presentation = renderElement(myItems[0]) + assert "Param" == presentation.itemText + assert presentation.tailText == " (type parameter of Foo)" + assert !presentation.typeText + assert !presentation.icon + assert !presentation.itemTextBold + + presentation = renderElement(myItems[1]) + assert "Param2" == presentation.itemText + assert presentation.tailText == " (type parameter of goo)" + } + public void testMethodItemPresentation() { configure() LookupElementPresentation presentation = renderElement(myItems[0]) @@ -839,7 +853,7 @@ public class ListUtils { final String path = getTestName(false) + ".java"; configureByFile(path); checkResultByFile(path); - assertStringItems("fai1", "fai2"); + assertStringItems("fai1", "fai2", "FunctionalInterface"); } public void testProtectedInaccessibleOnSecondInvocation() throws Throwable { @@ -1302,5 +1316,20 @@ class XInternalError {} assert lookup.items.size() == 1 } + public void testImplementViaCompletion() { + configure() + myFixture.assertPreferredCompletionItems 0, 'private', 'protected', 'public', 'public void run' + def item = lookup.items[3] + + def p = LookupElementPresentation.renderElement(item) + assert p.itemText == 'public void run' + assert p.tailText == '(s, myInt) {...}' + assert p.typeText == 'Foo' + + lookup.currentItem = item + myFixture.type('\n') + checkResult() + } + } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java index 06beba331d5c..f8ea1ba949bc 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType18CompletionTest.java @@ -17,7 +17,6 @@ package com.intellij.codeInsight.completion; import com.intellij.JavaTestUtil; import com.intellij.codeInsight.lookup.Lookup; -import com.intellij.codeInsight.lookup.LookupElementPresentation; import com.intellij.testFramework.LightProjectDescriptor; import org.jetbrains.annotations.NotNull; @@ -63,6 +62,10 @@ public class SmartType18CompletionTest extends LightFixtureCompletionTestCase { doTest(); } + public void testIgnoreDefaultMethods() { + doTest(); + } + private void doTest() { configureByFile("/" + getTestName(false) + ".java"); assertNotNull(myItems); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy index b14a645bc5ae..fa418ec9c5fb 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionOrderingTest.groovy @@ -95,7 +95,7 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase { } public void testDontPreferKeywords() throws Throwable { - checkPreferredItems(0, "o1", "foo", "name", "this", "getClass"); + checkPreferredItems(0, "o1", "foo", "name", "this"); } public void testEnumValueOf() throws Throwable { @@ -129,11 +129,11 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase { } public void testSmartEquals2() throws Throwable { - checkPreferredItems(0, "foo", "this", "o", "s", "getClass"); + checkPreferredItems(0, "foo", "this", "o", "s"); } public void testSmartEquals3() throws Throwable { - checkPreferredItems(0, "b", "this", "a", "z", "getClass"); + checkPreferredItems(0, "b", "this", "a", "z"); } public void testSmartCollectionsNew() throws Throwable { @@ -222,7 +222,7 @@ public class SmartTypeCompletionOrderingTest extends CompletionSortingTestCase { } public void testFactoryMethodForDefaultType() throws Throwable { - checkPreferredItems(0, "create", "this", "getClass"); + checkPreferredItems(0, "create", "this"); } public void testLocalVarsBeforeClassLiterals() throws Throwable { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java index 7741a09efe0a..a8fc06a8faad 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java @@ -348,6 +348,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase { String path = "/generics"; configureByFile(path + "/before9.java"); + selectItem(myItems[1]); checkResultByFile(path + "/after9.java"); } @@ -421,7 +422,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase { public void testArrayAccessIndex() throws Throwable { doTest(); } - public void testThrowExceptionConstructor() throws Throwable { doTest(); } + public void testThrowExceptionConstructor() throws Throwable { doTest('\n'); } public void testJavadocThrows() throws Throwable { doTest(); } @@ -470,7 +471,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase { public void testVoidExpectedType() throws Throwable { configureByTestName(); - assertStringItems("notify", "notifyAll", "wait", "wait", "wait", "getClass", "equals", "hashCode", "toString"); + assertStringItems("notify", "notifyAll", "wait", "wait", "wait", "equals", "hashCode", "toString", "getClass"); type("eq"); assertEquals("equals", assertOneElement(getLookup().getItems()).getLookupString()); select(); @@ -594,16 +595,18 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase { public void testNewVararg() throws Throwable { configureByTestName(); - assertStringItems("Foo", "Foo"); + assertStringItems("Foo", "Foo", "Foo"); assertEquals("{...} (default package)", LookupElementPresentation.renderElement(myItems[0]).getTailText()); assertEquals("[] (default package)", LookupElementPresentation.renderElement(myItems[1]).getTailText()); + assertEquals("[]{...} (default package)", LookupElementPresentation.renderElement(myItems[2]).getTailText()); } public void testNewVararg2() throws Throwable { configureByTestName(); - assertStringItems("String", "String"); + assertStringItems("String", "String", "String"); assertEquals(" (java.lang)", LookupElementPresentation.renderElement(myItems[0]).getTailText()); assertEquals("[] (java.lang)", LookupElementPresentation.renderElement(myItems[1]).getTailText()); + assertEquals("[]{...} (java.lang)", LookupElementPresentation.renderElement(myItems[2]).getTailText()); } public void testNewByteArray() { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java index a5cdf9d20882..076773a62e34 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -27,7 +27,6 @@ import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -50,8 +49,8 @@ import java.io.File; import java.util.Collection; /** - * This class intended for "heavily-loaded" tests only, e.g. those need to setup separate project directory structure to run - * For "lightweight" tests use LightAdvHighlightingTest + * This class intended for "heavily-loaded" tests only, e.g. those need to setup separate project directory structure to run. + * For "lightweight" tests use LightAdvHighlightingTest. */ public class AdvHighlightingTest extends DaemonAnalyzerTestCase { @NonNls private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/advHighlighting"; @@ -158,7 +157,7 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase { doTest(BASE_PATH + "/alreadyImportedClass/pack/AlreadyImportedClass.java", BASE_PATH + "/alreadyImportedClass", false, false); } - public void testImportDefaultPackage() throws Exception { + public void testImportDefaultPackage1() throws Exception { doTest(BASE_PATH + "/importDefaultPackage/x/Usage.java", BASE_PATH + "/importDefaultPackage", false, false); } @@ -166,6 +165,10 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase { doTest(BASE_PATH + "/importDefaultPackage/x/ImportOnDemandUsage.java", BASE_PATH + "/importDefaultPackage", false, false); } + public void testImportDefaultPackage3() throws Exception { + doTest(BASE_PATH + "/importDefaultPackage/Test.java", BASE_PATH + "/importDefaultPackage", false, false); + } + public void testImportDefaultPackageInvalid() throws Exception { doTest(BASE_PATH + "/importDefaultPackage/x/InvalidUse.java", BASE_PATH + "/importDefaultPackage", false, false); } @@ -232,15 +235,16 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase { public void testMultiJDKConflict() throws Exception { String path = PathManagerEx.getTestDataPath() + BASE_PATH + "/" + getTestName(true); VirtualFile root = LocalFileSystem.getInstance().findFileByIoFile(new File(path)); + assert root != null : path; loadAllModulesUnder(root); + ModuleManager moduleManager = ModuleManager.getInstance(getProject()); - final Module java4 = moduleManager.findModuleByName("java4"); + Module java4 = moduleManager.findModuleByName("java4"); Module java5 = moduleManager.findModuleByName("java5"); ModuleRootModificationUtil.setModuleSdk(java4, IdeaTestUtil.getMockJdk17("java 1.4")); ModuleRootModificationUtil.setModuleSdk(java5, IdeaTestUtil.getMockJdk17("java 1.5")); ModuleRootModificationUtil.addDependency(java5, java4); - assert root != null; configureByExistingFile(root.findFileByRelativePath("moduleJava5/com/Java5.java")); Collection<HighlightInfo> infos = highlightErrors(); assertEmpty(infos); @@ -249,9 +253,9 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase { public void testSameFQNClasses() throws Exception { String path = PathManagerEx.getTestDataPath() + BASE_PATH + "/" + getTestName(true); VirtualFile root = LocalFileSystem.getInstance().findFileByIoFile(new File(path)); + assert root != null : path; loadAllModulesUnder(root); - assert root != null; configureByExistingFile(root.findFileByRelativePath("client/src/BugTest.java")); Collection<HighlightInfo> infos = highlightErrors(); assertEmpty(infos); @@ -260,9 +264,9 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase { public void testSameClassesInSourceAndLib() throws Exception { String path = PathManagerEx.getTestDataPath() + BASE_PATH + "/" + getTestName(true); VirtualFile root = LocalFileSystem.getInstance().findFileByIoFile(new File(path)); + assert root != null : path; loadAllModulesUnder(root); - assert root != null; configureByExistingFile(root.findFileByRelativePath("src/ppp/SomeClass.java")); PsiField field = ((PsiJavaFile)myFile).getClasses()[0].findFieldByName("f", false); assert field != null; @@ -270,8 +274,8 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase { assert aClass != null; assertEquals("ppp.BadClass", aClass.getQualifiedName()); //lies in source - final VirtualFile vFile1 = myFile.getVirtualFile(); - final VirtualFile vFile2 = aClass.getContainingFile().getVirtualFile(); + VirtualFile vFile1 = myFile.getVirtualFile(); + VirtualFile vFile2 = aClass.getContainingFile().getVirtualFile(); assert vFile1 != null; assert vFile2 != null; assertEquals(vFile1.getParent(), vFile2.getParent()); @@ -281,4 +285,28 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase { LanguageLevelProjectExtension.getInstance(myProject).setLanguageLevel(LanguageLevel.JDK_1_4); doTest(BASE_PATH + "/notAKeywords/Test.java", BASE_PATH + "/notAKeywords", false, false); } + + public void testPackageAndClassConflict11() throws Exception { + doTest(BASE_PATH + "/packageClassClash1/pkg/sub/Test.java", BASE_PATH + "/packageClassClash1", false, false); + } + + public void testPackageAndClassConflict12() throws Exception { + doTest(BASE_PATH + "/packageClassClash1/pkg/sub.java", BASE_PATH + "/packageClassClash1", false, false); + } + + public void testPackageAndClassConflict21() throws Exception { + doTest(BASE_PATH + "/packageClassClash2/pkg/sub/Test.java", BASE_PATH + "/packageClassClash2", false, false); + } + + public void testPackageAndClassConflict22() throws Exception { + doTest(BASE_PATH + "/packageClassClash2/pkg/Sub.java", BASE_PATH + "/packageClassClash2", false, false); + } + + public void testDefaultPackageAndClassConflict() throws Exception { + doTest(BASE_PATH + "/lang.java", false, false); + } + + public void testPackageObscuring() throws Exception { + doTest(BASE_PATH + "/packageObscuring/main/Main.java", BASE_PATH + "/packageObscuring", false, false); + } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AmbiguousMethodCallTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AmbiguousMethodCallTest.java index c716dbfab8c4..dfb7db246247 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AmbiguousMethodCallTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AmbiguousMethodCallTest.java @@ -22,6 +22,7 @@ import com.intellij.codeInspection.redundantCast.RedundantCastInspection; import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; /** * This class is for "lightweight" tests only, i.e. those which can run inside default light project set up @@ -40,6 +41,7 @@ public class AmbiguousMethodCallTest extends LightDaemonAnalyzerTestCase { doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkWeakWarnings, checkInfos); } + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java index b1b0fcb3b5b0..678bb665de9e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -29,10 +29,12 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { @NonNls private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/genericsHighlighting"; + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{new UncheckedWarningLocalInspection(), new UnusedSymbolLocalInspection(), new UnusedImportLocalInspection()}; @@ -199,6 +201,9 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA67597() { doTest5(false); } public void testIDEA57539() { doTest5(false); } public void testIDEA67570() { doTest5(false); } + public void testIDEA99061() { doTest5(false); } + public void testIDEA99347() { doTest5(false); } + public void testIDEA86875() { doTest5(false); } public void testJavaUtilCollections_NoVerify() throws Exception { PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule())); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocHighlightingTest.java index 1c63f947f882..0c561dfdace5 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocHighlightingTest.java @@ -18,6 +18,7 @@ public class JavadocHighlightingTest extends LightDaemonAnalyzerTestCase { return JavaTestUtil.getJavaTestDataPath(); } + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk6Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk6Test.java new file mode 100644 index 000000000000..02de38b62f5e --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk6Test.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.daemon; + +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.compiler.JavacQuirksInspection; +import com.intellij.codeInspection.redundantCast.RedundantCastInspection; +import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection; +import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; +import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.openapi.projectRoots.JavaVersionService; +import com.intellij.openapi.projectRoots.JavaVersionServiceImpl; +import com.intellij.pom.java.LanguageLevel; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +/** + * This class is for "lightweight" tests only, i.e. those which can run inside default light project set up + * For "heavyweight" tests use AdvHighlightingTest + */ +public class LightAdvHighlightingJdk6Test extends LightDaemonAnalyzerTestCase { + @NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/advHighlighting6"; + + private void doTest(boolean checkWarnings, boolean checkInfos, Class<?>... classes) { + setLanguageLevel(LanguageLevel.JDK_1_6); + ((JavaVersionServiceImpl)JavaVersionService.getInstance()).setTestVersion(JavaSdkVersion.JDK_1_6, myTestRootDisposable); + enableInspectionTools(classes); + doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkInfos); + } + + private void doTest(boolean checkWarnings, boolean checkWeakWarnings, boolean checkInfos, Class<?>... classes) { + enableInspectionTools(classes); + doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkWeakWarnings, checkInfos); + } + + @NotNull + @Override + protected LocalInspectionTool[] configureLocalInspectionTools() { + return new LocalInspectionTool[]{ + new UnusedSymbolLocalInspection(), + new UncheckedWarningLocalInspection(), + new JavacQuirksInspection(), + new RedundantCastInspection() + }; + } + + public void testJavacQuirks() throws Exception { setLanguageLevel(LanguageLevel.JDK_1_6); doTest(true, false); } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java index 9b72a23757f7..53710582edd5 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java @@ -21,7 +21,6 @@ import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.compiler.JavacQuirksInspection; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; import com.intellij.codeInspection.defUse.DefUseInspection; -import com.intellij.codeInspection.deprecation.DeprecatedDefenderSyntaxInspection; import com.intellij.codeInspection.redundantCast.RedundantCastInspection; import com.intellij.codeInspection.reference.EntryPoint; import com.intellij.codeInspection.reference.RefElement; @@ -30,6 +29,9 @@ import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.extensions.ExtensionPoint; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.openapi.projectRoots.JavaVersionService; +import com.intellij.openapi.projectRoots.JavaVersionServiceImpl; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.PsiElement; import org.jdom.Element; @@ -46,6 +48,8 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { @NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/advHighlighting7"; private void doTest(boolean checkWarnings, boolean checkInfos, Class<?>... classes) { + setLanguageLevel(LanguageLevel.JDK_1_7); + ((JavaVersionServiceImpl)JavaVersionService.getInstance()).setTestVersion(JavaSdkVersion.JDK_1_7, myTestRootDisposable); enableInspectionTools(classes); doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkInfos); } @@ -55,6 +59,7 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkWeakWarnings, checkInfos); } + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ @@ -93,7 +98,7 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { public void testDiamondNeg12() throws Exception { doTest(false, false); } public void testDiamondNeg13() throws Exception { doTest(false, false); } public void testDiamondNeg14() throws Exception { doTest(false, false); } - public void testDiamondMisc() throws Exception { setLanguageLevel(LanguageLevel.JDK_1_7); doTest(false, false); } + public void testDiamondMisc() throws Exception { doTest(false, false); } public void testHighlightInaccessibleFromClassModifierList() throws Exception { doTest(false, false); } public void testInnerInTypeArguments() throws Exception { doTest(false, false); } @@ -129,7 +134,6 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { } } - public void testJavacQuirks() throws Exception { setLanguageLevel(LanguageLevel.JDK_1_6); doTest(true, false); } public void testNumericLiterals() throws Exception { doTest(false, false); } public void testMultiCatch() throws Exception { doTest(false, false); } public void testTryWithResources() throws Exception { doTest(false, false); } @@ -146,8 +150,6 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { public void testExtendsBound() throws Exception { doTest(false, false); } public void testIDEA84533() throws Exception { doTest(false, false); } public void testClassLiteral() throws Exception { doTest(false, false); } - public void testExtensionMethods() throws Exception { doTest(false, false); } - public void testExtensionMethodSyntax() throws Exception { doTest(true, false, DeprecatedDefenderSyntaxInspection.class); } public void testMethodReferences() throws Exception { doTest(false, true, false); } public void testUsedMethodsByMethodReferences() throws Exception { doTest(true, true, false); } public void testLambdaExpressions() throws Exception { doTest(false, true, false); } @@ -157,9 +159,11 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { public void testUncheckedWarningIDEA70620() throws Exception { doTest(true, false); } public void testUncheckedWarningIDEA60166() throws Exception { doTest(true, false); } public void testUncheckedWarningIDEA21432() throws Exception { doTest(true, false); } + public void testUncheckedWarningIDEA99357() throws Exception { doTest(true, false); } public void testUncheckedWarningIDEA26738() throws Exception { doTest(true, false); } - public void testDefaultMethodVisibility() throws Exception { doTest(true, false); } + public void testUncheckedWarningIDEA99536() throws Exception { doTest(true, false); } public void testEnclosingInstance() throws Exception { doTest(false, false); } public void testWrongArgsAndUnknownTypeParams() throws Exception { doTest(false, false); } public void testAmbiguousMethodCallIDEA97983() throws Exception { doTest(false, false); } + public void testAmbiguousMethodCallIDEA100314() throws Exception { doTest(false, false); } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java index 99b1ebcd6de2..3f4c1500c9fd 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java @@ -73,6 +73,7 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase { setLanguageLevel(LanguageLevel.JDK_1_4); } + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ @@ -360,4 +361,5 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase { public void testThisBeforeSuper() throws Exception { doTest(false, false); } public void testExplicitConstructorInvocation() throws Exception { doTest(false, false); } public void testThisInInterface() throws Exception { doTest(false, false); } + public void testInnerClassConstantReference() throws Exception { doTest(false, false); } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LossyEncodingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LossyEncodingTest.java index bac292138b6b..072726efe7fe 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LossyEncodingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LossyEncodingTest.java @@ -35,6 +35,7 @@ import com.intellij.openapi.vfs.encoding.EncodingManager; import com.intellij.openapi.vfs.encoding.EncodingProjectManager; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import java.nio.charset.Charset; import java.util.Collection; @@ -43,6 +44,7 @@ import java.util.List; public class LossyEncodingTest extends LightDaemonAnalyzerTestCase { @NonNls private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lossyEncoding"; + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{new LossyEncodingInspection()}; @@ -50,7 +52,9 @@ public class LossyEncodingTest extends LightDaemonAnalyzerTestCase { public void testText() throws Exception { doTest("Text.txt"); - EncodingManager.getInstance().setEncoding(myVFile, Charset.forName("US-ASCII")); + Charset ascii = CharsetToolkit.forName("US-ASCII"); + EncodingManager.getInstance().setEncoding(myVFile, ascii); + assertEquals(ascii, myVFile.getCharset()); int start = myEditor.getCaretModel().getOffset(); type((char)0x445); type((char)0x438); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/SuppressWarningsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/SuppressWarningsTest.java index 4bdee1a1897e..6e68611e77ff 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/SuppressWarningsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/SuppressWarningsTest.java @@ -23,6 +23,7 @@ package com.intellij.codeInsight.daemon; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; public class SuppressWarningsTest extends LightDaemonAnalyzerTestCase { @NonNls private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/advHighlighting"; @@ -31,6 +32,7 @@ public class SuppressWarningsTest extends LightDaemonAnalyzerTestCase { doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false); } + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{new UnusedSymbolLocalInspection()}; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java new file mode 100644 index 000000000000..762814e6049c --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.daemon.lambda; + +import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; +import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.openapi.projectRoots.JavaVersionService; +import com.intellij.openapi.projectRoots.JavaVersionServiceImpl; +import org.jetbrains.annotations.NonNls; + +public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase { + @NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/graphInference"; + + public void testNestedCalls() throws Exception { + doTest(); + } + + public void testNestedCallsSameMethod() throws Exception { + doTest(); + } + + public void testChainedInference() throws Exception { + doTest(); + } + + public void testChainedInference1() throws Exception { + doTest(); + } + + public void testReturnStmt() throws Exception { + doTest(); + } + + public void testInferenceFromSiblings() throws Exception { + doTest(); + } + + private void doTest() throws Exception { + doTest(false); + } + + private void doTest(final boolean checkWarnings) throws Exception { + ((JavaVersionServiceImpl)JavaVersionService.getInstance()).setTestVersion(JavaSdkVersion.JDK_1_8, getTestRootDisposable()); + doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java new file mode 100644 index 000000000000..9778a6ae2886 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.daemon.lambda; + +import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; +import com.intellij.codeInspection.deprecation.DeprecatedDefenderSyntaxInspection; +import org.jetbrains.annotations.NonNls; + +public class Interface8MethodsHighlightingTest extends LightDaemonAnalyzerTestCase { + @NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods"; + + public void testStaticMethod() throws Exception { + doTest(); + } + + public void testNotInheritFromUnrelatedDefault() throws Exception { doTest(true, false); } + public void testDefaultMethodVisibility() throws Exception { doTest(true, false); } + public void testInheritUnrelatedDefaults() throws Exception { doTest(true, false); } + public void testExtensionMethods() throws Exception { doTest(false, false); } + public void testExtensionMethodSyntax() throws Exception { + enableInspectionTools(DeprecatedDefenderSyntaxInspection.class); + doTest(true, false); + } + + private void doTest() throws Exception { + doTest(false, false); + } + + private void doTest(final boolean checkWarnings, final boolean checkInfos) throws Exception { + doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, checkInfos); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java index 6b9e16ae63e0..a88f0c8f1dc2 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java @@ -16,11 +16,22 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { @NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/highlighting"; + @NotNull + @Override + protected LocalInspectionTool[] configureLocalInspectionTools() { + return new LocalInspectionTool[]{ + new UnusedSymbolLocalInspection(), + }; + } + public void testStaticAccess() throws Exception { doTest(); } @@ -28,11 +39,11 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void testEffectiveFinal() throws Exception { doTest(); } - + public void testReassignUsedVars() throws Exception { doTest(); } - + public void testLambdaContext() throws Exception { doTest(); } @@ -40,7 +51,7 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void testReturnTypeCompatibility() throws Exception { doTest(); } - + public void testTypeArgsConsistency() throws Exception { doTest(); } @@ -55,7 +66,7 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void testTypeArgsConsistencyWithoutParams() throws Exception { doTest(); - } + } public void testIncompatibleReturnTypes() throws Exception { doTest(); @@ -72,7 +83,7 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void testInferFromTypeArgs() throws Exception { doTest(); } - + public void testAmbiguity1() throws Exception { doTest(); } @@ -80,7 +91,7 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void _testAmbiguity2() throws Exception { doTest(); } - + public void testAmbiguityVarargs() throws Exception { doTest(); } @@ -88,7 +99,7 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void testAmbiguityRawGenerics() throws Exception { doTest(); } - + public void testDefaultMethod() throws Exception { doTest(); } @@ -104,7 +115,7 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void testReturnTypeCompatibility1() throws Exception { doTest(); } - + public void testNoInferenceResult() throws Exception { doTest(); } @@ -128,7 +139,7 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void testConditionalExpr() throws Exception { doTest(); } - + public void testIncompleteSubst() throws Exception { doTest(); } @@ -141,10 +152,14 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testUnhandledExceptions() throws Exception { + doTest(); + } + public void testReturnValue() throws Exception { doTest(); } - + public void testAlreadyUsedParamName() throws Exception { doTest(); } @@ -177,7 +192,27 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testIntersectionTypeInCast() throws Exception { + doTest(); + } + + public void testAmbiguitySpecificReturn() throws Exception { + doTest(true); + } + + public void testFunctionalInterfaceAnnotation() throws Exception { + doTest(); + } + + public void testAmbiguityReturnValueResolution() throws Exception { + doTest(); + } + private void doTest() throws Exception { - doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false); + doTest(false); + } + + private void doTest(final boolean checkWarnings) throws Exception { + doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false); } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java index ec1c083f372a..f93f7ac9025c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaParamsTest.java @@ -41,6 +41,10 @@ public class LambdaParamsTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testFormalParamsWithWildcards() throws Exception { + doTest(); + } + private void doTest() throws Exception { doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java index 5b38de1fb98e..997e0d563f1c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java @@ -22,10 +22,12 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.JavaVersionService; import com.intellij.openapi.projectRoots.JavaVersionServiceImpl; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; public class MethodRefHighlightingTest extends LightDaemonAnalyzerTestCase { @NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/methodRef"; + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ @@ -153,6 +155,22 @@ public class MethodRefHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(true); } + public void testIntersectionTypeInCast() throws Exception { + doTest(false); + } + + public void testUnhandledExceptions() throws Exception { + doTest(); + } + + public void testCapturedWildcards() throws Exception { + doTest(); + } + + public void testConstructorNonAbstractAbstractExpected() throws Exception { + doTest(); + } + private void doTest() throws Exception { doTest(false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java index 59683ae56fcc..f285ee489727 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java @@ -6,6 +6,7 @@ import com.intellij.codeInspection.nullable.NullableStuffInspection; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiMethod; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; public class AnnotateMethodTest extends LightQuickFix15TestCase { private boolean myMustBeAvailableAfterInvoke; @@ -15,6 +16,7 @@ public class AnnotateMethodTest extends LightQuickFix15TestCase { return "/codeInsight/daemonCodeAnalyzer/quickFix/annotateMethod"; } + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{new NullableStuffInspection(){ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2LambdaInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2LambdaInspectionTest.java index 892a92bc7569..c21eac60b308 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2LambdaInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2LambdaInspectionTest.java @@ -17,9 +17,11 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.AnonymousCanBeLambdaInspection; import com.intellij.codeInspection.LocalInspectionTool; +import org.jetbrains.annotations.NotNull; public class Anonymous2LambdaInspectionTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2MethodReferenceInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2MethodReferenceInspectionTest.java index e7fb3bedbf44..402409c6f6c4 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2MethodReferenceInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2MethodReferenceInspectionTest.java @@ -17,9 +17,11 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.AnonymousCanBeMethodReferenceInspection; import com.intellij.codeInspection.LocalInspectionTool; +import org.jetbrains.annotations.NotNull; public class Anonymous2MethodReferenceInspectionTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeNewOperatorTypeTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeNewOperatorTypeTest.java index 98e438b71345..db262aa3696c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeNewOperatorTypeTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeNewOperatorTypeTest.java @@ -1,8 +1,13 @@ package com.intellij.codeInsight.daemon.quickFix; -public class ChangeNewOperatorTypeTest extends LightQuickFix15TestCase { +import com.intellij.pom.java.LanguageLevel; - public void test() throws Exception { doAllTests(); } +public class ChangeNewOperatorTypeTest extends LightQuickFixTestCase { + + public void test() throws Exception { + setLanguageLevel(LanguageLevel.JDK_1_7); + doAllTests(); + } @Override protected String getBasePath() { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateClassFromNewTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateClassFromNewTest.java index b90ee60adde4..82fcd0e2e466 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateClassFromNewTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateClassFromNewTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; @@ -6,10 +21,9 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager; * @author ven */ public class CreateClassFromNewTest extends LightQuickFixTestCase { - public void test() throws Exception { CodeStyleSettingsManager.getSettings(getProject()).SPACE_BEFORE_CLASS_LBRACE = true; - doAllTests(); + doAllTests(); } @Override diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateConstructorParameterFromFieldTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateConstructorParameterFromFieldTest.java index 65c09a604bc5..94f8a9c65ce8 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateConstructorParameterFromFieldTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateConstructorParameterFromFieldTest.java @@ -2,11 +2,13 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; +import org.jetbrains.annotations.NotNull; /** * @author cdr */ public class CreateConstructorParameterFromFieldTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ new UnusedSymbolLocalInspection()}; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateInnerClassFromNewTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateInnerClassFromNewTest.java index 902f0ff881d9..7b53bd1505ae 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateInnerClassFromNewTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateInnerClassFromNewTest.java @@ -1,13 +1,30 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.codeInsight.daemon.quickFix; /** * @author yole */ public class CreateInnerClassFromNewTest extends LightQuickFixTestCase { - public void test() throws Exception { doAllTests(); } + public void test() throws Exception { + doAllTests(); + } @Override protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/createInnerClassFromNew"; } -}
\ No newline at end of file +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateMethodFromUsageTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateMethodFromUsageTest.java index 3ad579bdf7e8..393f5208cbb9 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateMethodFromUsageTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateMethodFromUsageTest.java @@ -3,7 +3,7 @@ package com.intellij.codeInsight.daemon.quickFix; /** * @author ven */ -public class CreateMethodFromUsageTest extends LightQuickFix15TestCase { +public class CreateMethodFromUsageTest extends LightQuickFixTestCase { public void test() throws Exception { doAllTests(); } @Override diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/EmptyIntentionInspectionQuickFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/EmptyIntentionInspectionQuickFixTest.java index a2fea9938009..0895fd970d43 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/EmptyIntentionInspectionQuickFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/EmptyIntentionInspectionQuickFixTest.java @@ -24,6 +24,7 @@ public class EmptyIntentionInspectionQuickFixTest extends LightQuickFixTestCase{ return "/codeInsight/daemonCodeAnalyzer/quickFix/emptyIntention"; } + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{new DefUseInspection(), new LocalInspectionTool() { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/EnableOptimizeImportsOnTheFlyTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/EnableOptimizeImportsOnTheFlyTest.java index e45590611ea0..3da506a90583 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/EnableOptimizeImportsOnTheFlyTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/EnableOptimizeImportsOnTheFlyTest.java @@ -4,9 +4,11 @@ import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection; +import org.jetbrains.annotations.NotNull; public class EnableOptimizeImportsOnTheFlyTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{new UnusedImportLocalInspection()}; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/FixAllQuickfixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/FixAllQuickfixTest.java index 8da26aa6bb27..3cfb844aaaee 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/FixAllQuickfixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/FixAllQuickfixTest.java @@ -7,8 +7,10 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.dataFlow.DataFlowInspection; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; public class FixAllQuickfixTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[] { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/GenerifyFileTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/GenerifyFileTest.java index 1d0d11432ad4..9907b329e760 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/GenerifyFileTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/GenerifyFileTest.java @@ -2,10 +2,12 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection; +import org.jetbrains.annotations.NotNull; public class GenerifyFileTest extends LightQuickFixAvailabilityTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[] {new UncheckedWarningLocalInspection()}; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/I18nQuickFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/I18nQuickFixTest.java index 2d6cb90a87bf..d55341d7af7e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/I18nQuickFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/I18nQuickFixTest.java @@ -4,6 +4,7 @@ import com.intellij.codeInsight.daemon.quickFix.LightQuickFix15TestCase; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.i18n.I18nInspection; import com.intellij.openapi.util.Comparing; +import org.jetbrains.annotations.NotNull; /** * @author yole @@ -11,6 +12,7 @@ import com.intellij.openapi.util.Comparing; public class I18nQuickFixTest extends LightQuickFix15TestCase { private boolean myMustBeAvailableAfterInvoke; + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{new I18nInspection()}; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/InitializeFinalFieldInConstructorFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/InitializeFinalFieldInConstructorFixTest.java index 4dadabcca79a..4b3c868eabce 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/InitializeFinalFieldInConstructorFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/InitializeFinalFieldInConstructorFixTest.java @@ -2,8 +2,10 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; +import org.jetbrains.annotations.NotNull; public class InitializeFinalFieldInConstructorFixTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ new UnusedSymbolLocalInspection()}; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/JavadocInspectionQuickFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/JavadocInspectionQuickFixTest.java index 6c40bf65b1db..17e729ebee42 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/JavadocInspectionQuickFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/JavadocInspectionQuickFixTest.java @@ -12,9 +12,11 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.javaDoc.JavaDocLocalInspection; +import org.jetbrains.annotations.NotNull; public class JavadocInspectionQuickFixTest extends LightQuickFix15TestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { final JavaDocLocalInspection javaDocLocalInspection = new JavaDocLocalInspection(); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Lambda2MethodReferenceInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Lambda2MethodReferenceInspectionTest.java index dfed9a8c0fd9..af915d61836b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Lambda2MethodReferenceInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Lambda2MethodReferenceInspectionTest.java @@ -17,9 +17,11 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LambdaCanBeMethReferenceInspection; import com.intellij.codeInspection.LocalInspectionTool; +import org.jetbrains.annotations.NotNull; public class Lambda2MethodReferenceInspectionTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/LightQuickFix15TestCase.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/LightQuickFix15TestCase.java index a97e7ae4bfb4..457d783a7bb4 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/LightQuickFix15TestCase.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/LightQuickFix15TestCase.java @@ -15,8 +15,15 @@ */ package com.intellij.codeInsight.daemon.quickFix; +import com.intellij.pom.java.LanguageLevel; + /** * @author ven */ public abstract class LightQuickFix15TestCase extends LightQuickFixTestCase { + @Override + protected void doAllTests() throws Exception { + setLanguageLevel(LanguageLevel.JDK_1_5); + super.doAllTests(); + } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ModifierTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ModifierTest.java index c0eaeb8c1352..6c578808307a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ModifierTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ModifierTest.java @@ -1,5 +1,7 @@ package com.intellij.codeInsight.daemon.quickFix; +import com.intellij.pom.java.LanguageLevel; + public class ModifierTest extends LightQuickFixTestCase { public void test() throws Exception { doAllTests(); } @@ -7,4 +9,9 @@ public class ModifierTest extends LightQuickFixTestCase { protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/modifier"; } + + @Override + protected LanguageLevel getLanguageLevel() { + return LanguageLevel.JDK_1_7; + } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaCodeBlockInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaCodeBlockInspectionTest.java index 9199e149583a..b5ed93893702 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaCodeBlockInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaCodeBlockInspectionTest.java @@ -17,9 +17,11 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.RedundantLambdaCodeBlockInspection; +import org.jetbrains.annotations.NotNull; public class RedundantLambdaCodeBlockInspectionTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantUncheckedSuppressionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantUncheckedSuppressionTest.java index 248fc1e0e32b..f341e1d6363c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantUncheckedSuppressionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantUncheckedSuppressionTest.java @@ -25,6 +25,7 @@ import org.jetbrains.annotations.NotNull; public class RemoveRedundantUncheckedSuppressionTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { final PossibleHeapPollutionVarargsInspection varargsInspection = new PossibleHeapPollutionVarargsInspection(); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveUnusedParameterTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveUnusedParameterTest.java index fade977647a2..fd6afa2fbadf 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveUnusedParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveUnusedParameterTest.java @@ -3,11 +3,13 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; +import org.jetbrains.annotations.NotNull; public class RemoveUnusedParameterTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ new UnusedSymbolLocalInspection()}; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveUnusedVariableTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveUnusedVariableTest.java index f1821a6d5e3b..41b0863ac461 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveUnusedVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveUnusedVariableTest.java @@ -3,8 +3,10 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; +import org.jetbrains.annotations.NotNull; public class RemoveUnusedVariableTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ new UnusedSymbolLocalInspection()}; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceWithTernaryOperatorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceWithTernaryOperatorTest.java index 6419088e9583..3692eecbf886 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceWithTernaryOperatorTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceWithTernaryOperatorTest.java @@ -23,8 +23,10 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.dataFlow.DataFlowInspection; import com.intellij.codeInspection.nullable.NullableStuffInspection; +import org.jetbrains.annotations.NotNull; public class ReplaceWithTernaryOperatorTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{new DataFlowInspection(), new NullableStuffInspection()}; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SafeVarargsCanBeUsedTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SafeVarargsCanBeUsedTest.java index 8b7212e527d7..6b4605b2565e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SafeVarargsCanBeUsedTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SafeVarargsCanBeUsedTest.java @@ -17,9 +17,11 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.PossibleHeapPollutionVarargsInspection; +import org.jetbrains.annotations.NotNull; public class SafeVarargsCanBeUsedTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Simplify2DiamondInspectionsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Simplify2DiamondInspectionsTest.java index 76136b5fb8ef..bd3f7a0c7731 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Simplify2DiamondInspectionsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Simplify2DiamondInspectionsTest.java @@ -17,10 +17,12 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.ExplicitTypeCanBeDiamondInspection; import com.intellij.codeInspection.LocalInspectionTool; +import org.jetbrains.annotations.NotNull; //todo test3 should be checked if it compiles - as now javac infers Object instead of String?! public class Simplify2DiamondInspectionsTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Suppress15InspectionsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Suppress15InspectionsTest.java index 9931d17a85bc..13ebabffecf8 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Suppress15InspectionsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Suppress15InspectionsTest.java @@ -26,6 +26,7 @@ import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspec import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclaration; import com.intellij.codeInspection.unusedParameters.UnusedParametersInspection; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; +import org.jetbrains.annotations.NotNull; public class Suppress15InspectionsTest extends LightQuickFixTestCase { @@ -35,6 +36,7 @@ public class Suppress15InspectionsTest extends LightQuickFixTestCase { enableInspectionTool(new GlobalInspectionToolWrapper(new UnusedParametersInspection())); } + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SuppressLocalInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SuppressLocalInspectionTest.java index c096ff5a6ac0..4f3a1bbef42a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SuppressLocalInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SuppressLocalInspectionTest.java @@ -5,6 +5,7 @@ import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.localCanBeFinal.LocalCanBeFinal; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.pom.java.LanguageLevel; +import org.jetbrains.annotations.NotNull; public class SuppressLocalInspectionTest extends LightQuickFixTestCase { @@ -15,6 +16,7 @@ public class SuppressLocalInspectionTest extends LightQuickFixTestCase { LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_3); } + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{new LocalCanBeFinal()}; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SuppressNonInspectionsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SuppressNonInspectionsTest.java index 04a6a0567eb2..78ecf4f3113b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SuppressNonInspectionsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SuppressNonInspectionsTest.java @@ -11,6 +11,7 @@ import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclaration; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.pom.java.LanguageLevel; +import org.jetbrains.annotations.NotNull; public class SuppressNonInspectionsTest extends LightQuickFixTestCase { @@ -21,6 +22,7 @@ public class SuppressNonInspectionsTest extends LightQuickFixTestCase { LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_3); } + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SurroundWithIfFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SurroundWithIfFixTest.java index 9a4a1699ccd5..19ed7fc148c4 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SurroundWithIfFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SurroundWithIfFixTest.java @@ -22,8 +22,10 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.dataFlow.DataFlowInspection; +import org.jetbrains.annotations.NotNull; public class SurroundWithIfFixTest extends LightQuickFixTestCase { + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{new DataFlowInspection()}; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/VariableTypeFromCallTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/VariableTypeFromCallTest.java index 2f940e97197a..6ee5908adc68 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/VariableTypeFromCallTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/VariableTypeFromCallTest.java @@ -16,7 +16,7 @@ package com.intellij.codeInsight.daemon.quickFix; -public class VariableTypeFromCallTest extends LightQuickFix15TestCase { +public class VariableTypeFromCallTest extends LightQuickFixTestCase { public void test() throws Exception { doAllTests(); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/documentation/RefConvertorsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/documentation/RefConvertorsTest.java new file mode 100644 index 000000000000..f5bd537a6788 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/documentation/RefConvertorsTest.java @@ -0,0 +1,100 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.documentation; + +import com.intellij.JavaTestUtil; +import com.intellij.codeInsight.javadoc.JavaDocExternalFilter; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.FileUtilRt; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.testFramework.LightCodeInsightTestCase; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; + +/** + * @author Denis Zhdanov + * @since 1/15/13 7:26 PM + */ +public class RefConvertorsTest extends LightCodeInsightTestCase { + + private File myExtractedImagesDir; + + @Override + protected void setUp() throws Exception { + super.setUp(); + String tempDirectory = FileUtilRt.getTempDirectory(); + myExtractedImagesDir = new File(tempDirectory, AbstractExternalFilter.QUICK_DOC_DIR_NAME); + } + + @Override + protected void tearDown() throws Exception { + FileUtilRt.delete(myExtractedImagesDir); + super.tearDown(); + } + + public void testImgInsideJar() throws Exception { + String imgJarName = "test-img"; + File imgJar = new File(myExtractedImagesDir, imgJarName + ".jar"); + boolean exist = FileUtil.createIfDoesntExist(imgJar); + assertTrue(exist); + + JarOutputStream out = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(imgJar))); + try { + out.putNextEntry(new JarEntry("resources/inherit.gif")); + FileInputStream fIn = new FileInputStream(JavaTestUtil.getJavaTestDataPath() + "/codeInsight/documentation/inherit.gif"); + try { + FileUtil.copy(fIn, out); + } + finally { + fIn.close(); + } + } + finally { + out.close(); + } + + String textBefore = + "<HTML>" + + "java.lang.Object\n" + + " <IMG SRC=\"../../../resources/inherit.gif\" ALT=\"extended by \"><B>org.bouncycastle.asn1.BERSequenceParser</B>\n" + + "</HTML>"; + + File f = new File(myExtractedImagesDir, imgJarName); + f = new File(f, "resources"); + File extractedImgFile = new File(f, "inherit.gif"); + String expectedTextAfter = String.format( + "<HTML>" + + "java.lang.Object\n" + + " <IMG SRC=\"%s%s\" ALT=\"extended by \"><B>org.bouncycastle.asn1.BERSequenceParser</B>\n" + + "</HTML>", + LocalFileSystem.PROTOCOL_PREFIX, + extractedImgFile.getAbsolutePath()); + + JavaDocExternalFilter filter = new JavaDocExternalFilter(getProject()); + String textAfter = filter.correctRefs( + String.format("%s%s!/org/bouncycastle/asn1/BERSequenceParser.html", JarFileSystem.PROTOCOL_PREFIX, imgJar.getAbsolutePath()), + textBefore + ); + assertEquals(expectedTextAfter, textAfter); + assertTrue(extractedImgFile.isFile()); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/intention/SplitIfActionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/intention/SplitIfActionTest.java index c6454a1e4ce0..c9653c3eabdb 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/intention/SplitIfActionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/intention/SplitIfActionTest.java @@ -10,51 +10,45 @@ import com.intellij.testFramework.LightCodeInsightTestCase; public class SplitIfActionTest extends LightCodeInsightTestCase { public void test1() throws Exception { CodeStyleSettingsManager.getSettings(getProject()).ELSE_ON_NEW_LINE= true; - configureByFile("/codeInsight/splitIfAction/before1.java"); - perform(); - checkResultByFile("/codeInsight/splitIfAction/after1.java"); + doTest(); } public void test2() throws Exception { - configureByFile("/codeInsight/splitIfAction/before2.java"); - perform(); - checkResultByFile("/codeInsight/splitIfAction/after2.java"); + doTest(); } public void test3() throws Exception { - configureByFile("/codeInsight/splitIfAction/before3.java"); - perform(); - checkResultByFile("/codeInsight/splitIfAction/after3.java"); + doTest(); } public void test4() throws Exception { - configureByFile("/codeInsight/splitIfAction/before4.java"); - perform(); - checkResultByFile("/codeInsight/splitIfAction/after4.java"); + doTest(); } public void test5() throws Exception { - configureByFile("/codeInsight/splitIfAction/before5.java"); - perform(); - checkResultByFile("/codeInsight/splitIfAction/after5.java"); + doTest(); } - public void test6() throws Exception { - configureByFile("/codeInsight/splitIfAction/beforeParenthesis.java"); - perform(); - checkResultByFile("/codeInsight/splitIfAction/afterParenthesis.java"); + public void testParenthesis() throws Exception { + doTest(); } - public void test7() throws Exception { - configureByFile("/codeInsight/splitIfAction/beforeOrParenthesis.java"); - perform(); - checkResultByFile("/codeInsight/splitIfAction/afterOrParenthesis.java"); + public void testOrParenthesis() throws Exception { + doTest(); } public void testComment() throws Exception { - configureByFile("/codeInsight/splitIfAction/beforeComment.java"); + doTest(); + } + + public void testWithoutSpaces() throws Exception { + doTest(); + } + + private void doTest() throws Exception { + configureByFile("/codeInsight/splitIfAction/before" + getTestName(false)+ ".java"); perform(); - checkResultByFile("/codeInsight/splitIfAction/afterComment.java"); + checkResultByFile("/codeInsight/splitIfAction/after" + getTestName(false) + ".java"); } public void test8() throws Exception { @@ -64,7 +58,6 @@ public class SplitIfActionTest extends LightCodeInsightTestCase { } - private void perform() throws Exception { SplitIfAction action = new SplitIfAction(); assertTrue(action.isAvailable(getProject(), getEditor(), getFile())); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java index 666709af1083..e6595b98b11a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java @@ -58,6 +58,10 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { public void testInitializerWithNew() throws Exception { doTestField(); } + + public void testInitializerWithReference() throws Exception { + doTestField(); + } private void doTestField() throws Exception { PsiClass psiClass = getTestClass(); @@ -80,6 +84,7 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { final File htmlPath = new File(JavaTestUtil.getJavaTestDataPath() + "/codeInsight/javadocIG/" + getTestName(true) + ".html"); String htmlText = FileUtil.loadFile(htmlPath); String docInfo = new JavaDocInfoGenerator(getProject(), field).generateDocInfo(null); + assertNotNull(docInfo); assertEquals(StringUtil.convertLineSeparators(htmlText.trim()), StringUtil.convertLineSeparators(docInfo.trim())); } @@ -90,6 +95,7 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { final String info = new JavaDocInfoGenerator(getProject(), JavaPsiFacade.getInstance(getProject()).findPackage(getTestName(true))).generateDocInfo(null); String htmlText = FileUtil.loadFile(new File(packageInfo + File.separator + "packageInfo.html")); + assertNotNull(info); assertEquals(StringUtil.convertLineSeparators(htmlText.trim()), StringUtil.convertLineSeparators(info.trim())); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy index bd3eb0a5ac68..d739f69d91c8 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy @@ -178,7 +178,7 @@ class Foo { assert !state } - public void "_test non-imported classes in className macro"() { + public void "test non-imported classes in className macro"() { myFixture.addClass('package bar; public class Bar {}') myFixture.configureByText 'a.java', ''' class Foo { diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java deleted file mode 100644 index 600b822e2780..000000000000 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.codeInspection; - -import com.intellij.JavaTestUtil; -import com.intellij.codeInsight.NullableNotNullManager; -import com.intellij.codeInspection.dataFlow.DataFlowInspection; -import com.intellij.openapi.Disposable; -import com.intellij.openapi.util.Disposer; -import com.intellij.pom.java.LanguageLevel; -import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; -import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase; - -/** - * @author peter - */ -public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCase { - @Override - protected void tuneFixture(JavaModuleFixtureBuilder moduleBuilder) { - moduleBuilder.setLanguageLevel(LanguageLevel.HIGHEST); - } - - @Override - protected String getTestDataPath() { - return JavaTestUtil.getJavaTestDataPath() + "/inspection/dataFlow/fixture/"; - } - - private void doTest() { - final DataFlowInspection inspection = new DataFlowInspection(); - inspection.SUGGEST_NULLABLE_ANNOTATIONS = true; - myFixture.enableInspections(inspection); - myFixture.testHighlighting(true, false, true, getTestName(false) + ".java"); - } - - public void testTryInAnonymous() throws Throwable { doTest(); } - public void testNullableAnonymousMethod() throws Throwable { doTest(); } - public void testNullableAnonymousParameter() throws Throwable { doTest(); } - public void testNullableAnonymousVolatile() throws Throwable { doTest(); } - public void testNullableAnonymousVolatileNotNull() throws Throwable { doTest(); } - public void testLocalClass() throws Throwable { doTest(); } - - public void testFieldInAnonymous() throws Throwable { doTest(); } - public void testFieldInitializerInAnonymous() throws Throwable { doTest(); } - public void testNullableField() throws Throwable { doTest(); } - public void testCanBeNullDoesntImplyIsNull() throws Throwable { doTest(); } - public void testAnnReport() throws Throwable { doTest(); } - - public void testBigMethodNotComplex() throws Throwable { doTest(); } - public void testBuildRegexpNotComplex() throws Throwable { doTest(); } - public void testTernaryInWhileNotComplex() throws Throwable { doTest(); } - public void testTryCatchInForNotComplex() throws Throwable { doTest(); } - public void testFieldChangedBetweenSynchronizedBlocks() throws Throwable { doTest(); } - - public void testGeneratedEquals() throws Throwable { doTest(); } - - public void testIDEA84489() throws Throwable { doTest(); } - public void testComparingToNotNullShouldNotAffectNullity() throws Throwable { doTest(); } - public void testStringTernaryAlwaysTrue() throws Throwable { doTest(); } - - public void testBoxing128() throws Throwable { doTest(); } - public void testFinalFieldsInitializedByAnnotatedParameters() throws Throwable { doTest(); } - public void testMultiCatch() throws Throwable { doTest(); } - public void testContinueFlushesLoopVariable() throws Throwable { doTest(); } - - public void testEqualsNotNull() throws Throwable { doTest(); } - public void testVisitFinallyOnce() throws Throwable { doTest(); } - public void testNotEqualsDoesntImplyNotNullity() throws Throwable { doTest(); } - public void testEqualsEnumConstant() throws Throwable { doTest(); } - public void testEqualsConstant() throws Throwable { doTest(); } - public void testFinalLoopVariableInstanceof() throws Throwable { doTest(); } - public void testGreaterIsNotEquals() throws Throwable { doTest(); } - public void testNotGreaterIsNotEquals() throws Throwable { doTest(); } - - public void testChainedFinalFieldsDfa() throws Throwable { doTest(); } - public void testFinalFieldsDifferentInstances() throws Throwable { doTest(); } - public void testThisFieldGetters() throws Throwable { doTest(); } - public void testChainedFinalFieldAccessorsDfa() throws Throwable { doTest(); } - - public void testAssigningUnknownToNullable() throws Throwable { doTest(); } - public void testAssigningClassLiteralToNullable() throws Throwable { doTest(); } - - public void testSynchronizingOnNullable() throws Throwable { doTest(); } - public void testReturningNullFromVoidMethod() throws Throwable { doTest(); } - - public void testCatchRuntimeException() throws Throwable { doTest(); } - - public void testAssertFailInCatch() throws Throwable { - myFixture.addClass("package org.junit; public class Assert { public static void fail() {}}"); - doTest(); - } - - public void testPreserveNullableOnUncheckedCast() throws Throwable { doTest(); } - - public void testPassingNullableIntoVararg() throws Throwable { doTest(); } - public void testEqualsImpliesNotNull() throws Throwable { doTest(); } - - public void testAnnotatedTypeParameters() throws Throwable { - setupCustomAnnotations(); - doTest(); - } - - private void setupCustomAnnotations() { - myFixture.addClass("package foo; public @interface Nullable {}"); - myFixture.addClass("package foo; public @interface NotNull {}"); - final NullableNotNullManager nnnManager = NullableNotNullManager.getInstance(getProject()); - nnnManager.setNotNulls("foo.NotNull"); - nnnManager.setNullables("foo.Nullable"); - Disposer.register(myTestRootDisposable, new Disposable() { - @Override - public void dispose() { - nnnManager.setNotNulls(); - nnnManager.setNullables(); - } - }); - } - - public void testSkipAssertions() { - final DataFlowInspection inspection = new DataFlowInspection(); - inspection.DONT_REPORT_TRUE_ASSERT_STATEMENTS = true; - myFixture.enableInspections(inspection); - myFixture.testHighlighting(true, false, true, getTestName(false) + ".java"); - } - - public void testCheckFieldInitializers() { - doTest(); - } - - public void testConstantDoubleComparisons() { doTest(); } - - public void _testMutableNullableFieldsTreatment() { doTest(); } - public void _testMutableVolatileNullableFieldsTreatment() { doTest(); } - public void testMutableNotAnnotatedFieldsTreatment() { doTest(); } - - public void testMethodCallFlushesField() { doTest(); } - public void testUnknownFloatMayBeNaN() { doTest(); } - public void testLastConstantConditionInAnd() { doTest(); } - - public void testTransientFinalField() { doTest(); } - public void _testSymmetricUncheckedCast() { doTest(); } - public void testNullCheckDoesntAffectUncheckedCast() { doTest(); } - - public void testNullableForeachVariable() { - setupCustomAnnotations(); - doTest(); - } - -} diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java index 480d955128bc..56fa8115d95f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java @@ -15,22 +15,147 @@ */ package com.intellij.codeInspection; -import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; +import com.intellij.JavaTestUtil; +import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.codeInspection.dataFlow.DataFlowInspection; -import org.jetbrains.annotations.NonNls; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; -public class DataFlowInspectionTest extends LightDaemonAnalyzerTestCase { - @NonNls static final String BASE_PATH = "/inspection/dataFlow"; +/** + * @author peter + */ +public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase { + + @Override + protected String getTestDataPath() { + return JavaTestUtil.getJavaTestDataPath() + "/inspection/dataFlow/fixture/"; + } private void doTest() { - doTest(BASE_PATH + "/" + getTestName(false) + ".java", true, false); + final DataFlowInspection inspection = new DataFlowInspection(); + inspection.SUGGEST_NULLABLE_ANNOTATIONS = true; + myFixture.enableInspections(inspection); + myFixture.testHighlighting(true, false, true, getTestName(false) + ".java"); } - @Override - protected LocalInspectionTool[] configureLocalInspectionTools() { - return new LocalInspectionTool[]{new DataFlowInspection()}; + public void testTryInAnonymous() throws Throwable { doTest(); } + public void testNullableAnonymousMethod() throws Throwable { doTest(); } + public void testNullableAnonymousParameter() throws Throwable { doTest(); } + public void testNullableAnonymousVolatile() throws Throwable { doTest(); } + public void testNullableAnonymousVolatileNotNull() throws Throwable { doTest(); } + public void testLocalClass() throws Throwable { doTest(); } + + public void testFieldInAnonymous() throws Throwable { doTest(); } + public void testFieldInitializerInAnonymous() throws Throwable { doTest(); } + public void testNullableField() throws Throwable { doTest(); } + public void testCanBeNullDoesntImplyIsNull() throws Throwable { doTest(); } + public void testAnnReport() throws Throwable { doTest(); } + + public void testBigMethodNotComplex() throws Throwable { doTest(); } + public void testBuildRegexpNotComplex() throws Throwable { doTest(); } + public void testTernaryInWhileNotComplex() throws Throwable { doTest(); } + public void testTryCatchInForNotComplex() throws Throwable { doTest(); } + public void testFieldChangedBetweenSynchronizedBlocks() throws Throwable { doTest(); } + + public void testGeneratedEquals() throws Throwable { doTest(); } + + public void testIDEA84489() throws Throwable { doTest(); } + public void testComparingToNotNullShouldNotAffectNullity() throws Throwable { doTest(); } + public void testStringTernaryAlwaysTrue() throws Throwable { doTest(); } + + public void testBoxing128() throws Throwable { doTest(); } + public void testFinalFieldsInitializedByAnnotatedParameters() throws Throwable { doTest(); } + public void testMultiCatch() throws Throwable { doTest(); } + public void testContinueFlushesLoopVariable() throws Throwable { doTest(); } + + public void testEqualsNotNull() throws Throwable { doTest(); } + public void testVisitFinallyOnce() throws Throwable { doTest(); } + public void testNotEqualsDoesntImplyNotNullity() throws Throwable { doTest(); } + public void testEqualsEnumConstant() throws Throwable { doTest(); } + public void testEqualsConstant() throws Throwable { doTest(); } + public void testFinalLoopVariableInstanceof() throws Throwable { doTest(); } + public void testGreaterIsNotEquals() throws Throwable { doTest(); } + public void testNotGreaterIsNotEquals() throws Throwable { doTest(); } + + public void testChainedFinalFieldsDfa() throws Throwable { doTest(); } + public void testFinalFieldsDifferentInstances() throws Throwable { doTest(); } + public void testThisFieldGetters() throws Throwable { doTest(); } + public void testChainedFinalFieldAccessorsDfa() throws Throwable { doTest(); } + + public void testAssigningUnknownToNullable() throws Throwable { doTest(); } + public void testAssigningClassLiteralToNullable() throws Throwable { doTest(); } + + public void testSynchronizingOnNullable() throws Throwable { doTest(); } + public void testReturningNullFromVoidMethod() throws Throwable { doTest(); } + + public void testCatchRuntimeException() throws Throwable { doTest(); } + + public void testAssertFailInCatch() throws Throwable { + myFixture.addClass("package org.junit; public class Assert { public static void fail() {}}"); + doTest(); + } + + public void testPreserveNullableOnUncheckedCast() throws Throwable { doTest(); } + + public void testPassingNullableIntoVararg() throws Throwable { doTest(); } + public void testEqualsImpliesNotNull() throws Throwable { doTest(); } + public void testEffectivelyUnqualified() throws Throwable { doTest(); } + + public void testAnnotatedTypeParameters() throws Throwable { + setupCustomAnnotations(); + doTest(); + } + + private void setupCustomAnnotations() { + myFixture.addClass("package foo; public @interface Nullable {}"); + myFixture.addClass("package foo; public @interface NotNull {}"); + final NullableNotNullManager nnnManager = NullableNotNullManager.getInstance(getProject()); + nnnManager.setNotNulls("foo.NotNull"); + nnnManager.setNullables("foo.Nullable"); + Disposer.register(myTestRootDisposable, new Disposable() { + @Override + public void dispose() { + nnnManager.setNotNulls(); + nnnManager.setNullables(); + } + }); + } + + public void testSkipAssertions() { + final DataFlowInspection inspection = new DataFlowInspection(); + inspection.DONT_REPORT_TRUE_ASSERT_STATEMENTS = true; + myFixture.enableInspections(inspection); + myFixture.testHighlighting(true, false, true, getTestName(false) + ".java"); + } + + public void testCheckFieldInitializers() { + doTest(); + } + + public void testConstantDoubleComparisons() { doTest(); } + + public void testMutableNullableFieldsTreatment() { doTest(); } + public void testMutableVolatileNullableFieldsTreatment() { doTest(); } + public void testMutableNotAnnotatedFieldsTreatment() { doTest(); } + + public void testMethodCallFlushesField() { doTest(); } + public void testUnknownFloatMayBeNaN() { doTest(); } + public void testLastConstantConditionInAnd() { doTest(); } + + public void testTransientFinalField() { doTest(); } + public void _testSymmetricUncheckedCast() { doTest(); } + public void testNullCheckDoesntAffectUncheckedCast() { doTest(); } + + public void testNullableForeachVariable() { + setupCustomAnnotations(); + doTest(); } public void testTryWithResourcesNullability() { doTest(); } public void testTryWithResourcesInstanceOf() { doTest(); } + public void testOmnipresentExceptions() { doTest(); } + + public void testEqualsHasNoSideEffects() { doTest(); } + } diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java index 07d2bf4fc99e..480a910cc394 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTestSuite.java @@ -23,7 +23,6 @@ public class DataFlowInspectionTestSuite { public static Test suite() { TestSuite suite = new TestSuite(); suite.addTestSuite(DataFlowInspectionTest.class); - suite.addTestSuite(DataFlowInspectionFixtureTest.class); suite.addTestSuite(DataFlowInspectionAncientTest.class); suite.addTestSuite(SliceTreeTest.class); return suite; diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/GlobalInspectionContextTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/GlobalInspectionContextTest.java index dab2baf370b2..872ae1277119 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/GlobalInspectionContextTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/GlobalInspectionContextTest.java @@ -21,7 +21,6 @@ import com.intellij.codeInsight.CodeInsightTestCase; import com.intellij.codeInspection.actions.RunInspectionIntention; import com.intellij.codeInspection.ex.*; import com.intellij.codeInspection.visibility.VisibilityInspection; -import com.intellij.profile.codeInspection.InspectionProfileManager; import java.util.ArrayList; import java.util.Arrays; @@ -56,7 +55,7 @@ public class GlobalInspectionContextTest extends CodeInsightTestCase { } public void testRunInspectionContext() throws Exception { - InspectionProfile profile = (InspectionProfile)InspectionProfileManager.getInstance().getRootProfile(); + InspectionProfile profile = new InspectionProfileImpl("foo"); InspectionProfileEntry[] tools = profile.getInspectionTools(null); for (InspectionProfileEntry tool : tools) { if (!tool.isEnabledByDefault()) { diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/InspectionProfileTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/InspectionProfileTest.java index 409426b19c0b..b8ad3a04614d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/InspectionProfileTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/InspectionProfileTest.java @@ -16,6 +16,7 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.daemon.HighlightDisplayKey; +import com.intellij.codeInspection.dataFlow.DataFlowInspection; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; import com.intellij.codeInspection.ex.*; import com.intellij.openapi.util.JDOMUtil; @@ -254,7 +255,8 @@ public class InspectionProfileTest extends LightIdeaTestCase { assertEquals(0, countInitializedTools(profile)); InspectionProfileEntry[] tools = profile.getInspectionTools(null); assertTrue(tools.length > 0); - InspectionProfileEntry tool = tools[0]; + InspectionProfileEntry tool = profile.getInspectionTool(new DataFlowInspection().getShortName()); + assertNotNull(tool); String id = tool.getShortName(); System.out.println(id); if (profile.isToolEnabled(HighlightDisplayKey.findById(id))) { @@ -263,9 +265,15 @@ public class InspectionProfileTest extends LightIdeaTestCase { else { profile.enableTool(id); } + assertEquals(0, countInitializedTools(profile)); profile.writeExternal(new Element("profile")); List<InspectionProfileEntry> initializedTools = getInitializedTools(profile); - assertEquals(initializedTools.toString(), 1, initializedTools.size()); + if (initializedTools.size() != 1) { + for (InspectionProfileEntry initializedTool : initializedTools) { + System.out.println(initializedTool.getShortName()); + } + fail(); + } } public void testInspectionInitializationForSerialization() throws Exception { diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/SingleInspectionProfilePanelTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/SingleInspectionProfilePanelTest.java index 01d2908f7c0c..ab3a853a96bb 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/SingleInspectionProfilePanelTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/SingleInspectionProfilePanelTest.java @@ -23,6 +23,7 @@ import com.intellij.openapi.project.ProjectManager; import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel; import com.intellij.testFramework.LightIdeaTestCase; +import org.jetbrains.annotations.NotNull; /** * @author Dmitry Avdeev @@ -46,19 +47,65 @@ public class SingleInspectionProfilePanelTest extends LightIdeaTestCase { panel.reset(); assertEquals(InspectionProfileTest.getInitializedTools(model).toString(), 0, InspectionProfileTest.countInitializedTools(model)); - LocalInspectionToolWrapper wrapper = (LocalInspectionToolWrapper)model.getInspectionTool(myInspection.getShortName()); - assert wrapper != null; - JavaDocLocalInspection tool = (JavaDocLocalInspection)wrapper.getTool(); + JavaDocLocalInspection tool = getInspection(model); assertEquals("", tool.myAdditionalJavadocTags); tool.myAdditionalJavadocTags = "foo"; model.setModified(true); panel.apply(); assertEquals(1, InspectionProfileTest.countInitializedTools(model)); - wrapper = (LocalInspectionToolWrapper)profile.getInspectionTool(myInspection.getShortName()); - assert wrapper != null; - tool = (JavaDocLocalInspection)wrapper.getTool(); - assertEquals("foo", tool.myAdditionalJavadocTags); + assertEquals("foo", getInspection(profile).myAdditionalJavadocTags); + } + + public void testModifyInstantiatedTool() throws Exception { + Project project = ProjectManager.getInstance().getDefaultProject(); + InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(project); + InspectionProfileImpl profile = (InspectionProfileImpl)profileManager.getProfile(PROFILE); + profile.initInspectionTools(project); + assertEquals(0, InspectionProfileTest.countInitializedTools(profile)); + + JavaDocLocalInspection originalTool = getInspection(profile); + originalTool.myAdditionalJavadocTags = "foo"; + + InspectionProfileImpl model = (InspectionProfileImpl)profile.getModifiableModel(); + + SingleInspectionProfilePanel panel = new SingleInspectionProfilePanel(profileManager, PROFILE, model); + panel.setVisible(true); + panel.reset(); + assertEquals(InspectionProfileTest.getInitializedTools(model).toString(), 1, InspectionProfileTest.countInitializedTools(model)); + + JavaDocLocalInspection copyTool = getInspection(model); + copyTool.myAdditionalJavadocTags = "bar"; + + model.setModified(true); + panel.apply(); + assertEquals(1, InspectionProfileTest.countInitializedTools(model)); + + assertEquals("bar", getInspection(profile).myAdditionalJavadocTags); + } + + public void testDoNotChangeSettingsOnCancel() throws Exception { + Project project = ProjectManager.getInstance().getDefaultProject(); + InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(project); + InspectionProfileImpl profile = (InspectionProfileImpl)profileManager.getProfile(PROFILE); + profile.initInspectionTools(project); + assertEquals(0, InspectionProfileTest.countInitializedTools(profile)); + + JavaDocLocalInspection originalTool = getInspection(profile); + assertEquals("", originalTool.myAdditionalJavadocTags); + + InspectionProfileImpl model = (InspectionProfileImpl)profile.getModifiableModel(); + JavaDocLocalInspection copyTool = getInspection(model); + copyTool.myAdditionalJavadocTags = "foo"; + // this change IS NOT COMMITTED + + assertEquals("", getInspection(profile).myAdditionalJavadocTags); + } + + private JavaDocLocalInspection getInspection(InspectionProfileImpl profile) { + LocalInspectionToolWrapper original = (LocalInspectionToolWrapper)profile.getInspectionTool(myInspection.getShortName()); + assert original != null; + return (JavaDocLocalInspection)original.getTool(); } @Override @@ -75,6 +122,7 @@ public class SingleInspectionProfilePanelTest extends LightIdeaTestCase { private final JavaDocLocalInspection myInspection = new JavaDocLocalInspection(); + @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[] {myInspection}; diff --git a/java/java-tests/testSrc/com/intellij/lang/java/lexer/JavaLexerTest.java b/java/java-tests/testSrc/com/intellij/lang/java/lexer/JavaLexerTest.java index b1639bc4b4be..113211720e39 100644 --- a/java/java-tests/testSrc/com/intellij/lang/java/lexer/JavaLexerTest.java +++ b/java/java-tests/testSrc/com/intellij/lang/java/lexer/JavaLexerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -52,6 +52,17 @@ public class JavaLexerTest extends LexerTestCase { "DOUBLE_LITERAL ('3.14')\nWHITE_SPACE (' ')\n" + "DOUBLE_LITERAL ('1e-9d')\nWHITE_SPACE (' ')\n" + "DOUBLE_LITERAL ('1e137')"); + + doTest(". e0 x1 ax .e .p 08 .0e .0f", + "DOT ('.')\nWHITE_SPACE (' ')\n" + + "IDENTIFIER ('e0')\nWHITE_SPACE (' ')\n" + + "IDENTIFIER ('x1')\nWHITE_SPACE (' ')\n" + + "IDENTIFIER ('ax')\nWHITE_SPACE (' ')\n" + + "DOT ('.')\nIDENTIFIER ('e')\nWHITE_SPACE (' ')\n" + + "DOT ('.')\nIDENTIFIER ('p')\nWHITE_SPACE (' ')\n" + + "INTEGER_LITERAL ('08')\nWHITE_SPACE (' ')\n" + + "DOUBLE_LITERAL ('.0e')\nWHITE_SPACE (' ')\n" + + "FLOAT_LITERAL ('.0f')"); } public void testTigerNumericLiterals() { @@ -66,6 +77,9 @@ public class JavaLexerTest extends LexerTestCase { "DOUBLE_LITERAL ('0xab.P12')\nWHITE_SPACE (' ')\n" + "DOUBLE_LITERAL ('0x.abcP123d')\nWHITE_SPACE (' ')\n" + "DOUBLE_LITERAL ('0xabc.defP1234D')"); + + doTest("p0", + "IDENTIFIER ('p0')"); } public void testCoinNumericLiterals() { @@ -116,15 +130,18 @@ public class JavaLexerTest extends LexerTestCase { } public void testMalformedCoinLiterals() { - doTest("0_ _1 0_8 0x_f 0b_1 0B2 0x1.0_p-1 1.0e_1022", - "INTEGER_LITERAL ('0')\nIDENTIFIER ('_')\nWHITE_SPACE (' ')\n" + + doTest("_1 _b ._ 0_ 0_8 0x_f 0b_1 0B2 0x1.0_p-1 1.0e_1022 0._1", "IDENTIFIER ('_1')\nWHITE_SPACE (' ')\n" + - "INTEGER_LITERAL ('0')\nIDENTIFIER ('_8')\nWHITE_SPACE (' ')\n" + - "INTEGER_LITERAL ('0x')\nIDENTIFIER ('_f')\nWHITE_SPACE (' ')\n" + - "INTEGER_LITERAL ('0b')\nIDENTIFIER ('_1')\nWHITE_SPACE (' ')\n" + - "INTEGER_LITERAL ('0B')\nINTEGER_LITERAL ('2')\nWHITE_SPACE (' ')\n" + - "INTEGER_LITERAL ('0x1')\nDOUBLE_LITERAL ('.0')\nIDENTIFIER ('_p')\nMINUS ('-')\nINTEGER_LITERAL ('1')\nWHITE_SPACE (' ')\n" + - "DOUBLE_LITERAL ('1.0e')\nIDENTIFIER ('_1022')"); + "IDENTIFIER ('_b')\nWHITE_SPACE (' ')\n" + + "DOT ('.')\nIDENTIFIER ('_')\nWHITE_SPACE (' ')\n" + + "INTEGER_LITERAL ('0_')\nWHITE_SPACE (' ')\n" + + "INTEGER_LITERAL ('0_8')\nWHITE_SPACE (' ')\n" + + "INTEGER_LITERAL ('0x_f')\nWHITE_SPACE (' ')\n" + + "INTEGER_LITERAL ('0b_1')\nWHITE_SPACE (' ')\n" + + "INTEGER_LITERAL ('0B2')\nWHITE_SPACE (' ')\n" + + "DOUBLE_LITERAL ('0x1.0_p-1')\nWHITE_SPACE (' ')\n" + + "DOUBLE_LITERAL ('1.0e_1022')\nWHITE_SPACE (' ')\n" + + "DOUBLE_LITERAL ('0._1')"); } public void testMalformedOperators() { diff --git a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java index 88151e01c8fd..072e6b3ff52a 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java +++ b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java @@ -168,6 +168,8 @@ public class DirectoryIndexTest extends IdeaTestCase { }); myIndex = DirectoryIndex.getInstance(myProject); + // to not interfere with previous test firing vfs events + VirtualFileManager.getInstance().syncRefresh(); } private CompilerProjectExtension getCompilerProjectExtension() { diff --git a/java/java-tests/testSrc/com/intellij/psi/CoreJavaFileManagerTest.java b/java/java-tests/testSrc/com/intellij/psi/CoreJavaFileManagerTest.java new file mode 100644 index 000000000000..1cd630ccc2db --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/CoreJavaFileManagerTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2000-2013 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.core.CoreJavaFileManager; +import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.testFramework.PsiTestCase; +import com.intellij.testFramework.PsiTestUtil; + + +public class CoreJavaFileManagerTest extends PsiTestCase { + + public void testNotNullInnerClass() throws Exception { + VirtualFile root = PsiTestUtil.createTestProjectStructure(myProject, myModule, myFilesToDelete); + VirtualFile pkg = root.createChildDirectory(this, "foo"); + PsiDirectory dir = myPsiManager.findDirectory(pkg); + assertNotNull(dir); + String text = "package foo;\n\n" + + "public class Nested {\n" + + "public class InnerGeneral {}\n" + + "public class Inner$ {}\n" + + "\n" + + "public Inner$ inner() {\n" + + " return new Inner$();\n" + + "}\n" + + "\n" + + "}"; + PsiElement created = dir.add(PsiFileFactory.getInstance(getProject()).createFileFromText("Nested.java", JavaFileType.INSTANCE, text)); + + GlobalSearchScope scope = GlobalSearchScope.allScope(getProject()); + CoreJavaFileManager manager = new CoreJavaFileManager(myPsiManager); + manager.addToClasspath(root); + + PsiClass clazz = manager.findClass("foo.Nested", scope); + assertNotNull(clazz); + + PsiClass clazzInnerGeneral = manager.findClass("foo.Nested.InnerGeneral", scope); + assertNotNull(clazzInnerGeneral); + + PsiClass clazzInner$ = manager.findClass("foo.Nested.Inner$", scope); + assertNotNull(clazzInner$); + + PsiClass clazzInner$Wrong1 = manager.findClass("foo.Nested.Inner$X", scope); + assertNull(clazzInner$Wrong1); + + PsiClass clazzInner$Wrong2 = manager.findClass("foo.Nested.Inner$$X", scope); + assertNull(clazzInner$Wrong2); + + PsiClass clazzInner$Wrong3 = manager.findClass("foo.Nested.Inner$$", scope); + assertNull(clazzInner$Wrong3); + } + +} diff --git a/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java b/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java index 49fcdd73f39e..c1d20b4481c5 100644 --- a/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -41,6 +41,14 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; public class PsiConcurrencyStressTest extends PsiTestCase { + private static final boolean SKIP = "true".equalsIgnoreCase(System.getProperty("skip.psi.concurrency.test")); + + @Override + public void runBare() throws Throwable { + if (!SKIP) { + super.runBare(); + } + } @Override protected void setUp() throws Exception { diff --git a/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy b/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy index 2d0830edcbd5..b9a5732b83c6 100644 --- a/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy +++ b/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy @@ -61,10 +61,10 @@ class StubAstSwitchTest extends LightCodeInsightFixtureTestCase { } public void "test traversing PSI and switching concurrently"() { - int count = 1000 + int count = 100 List<PsiClass> classList = (0..<count).collect { myFixture.addClass("class Foo$it { " + - (0..<10).collect { "void foo$it(int i, boolean b, Object o) {}" }.join("\n") + + (0..<100).collect { "void foo$it(int i, boolean b, Object o) {}" }.join("\n") + " }") } CountDownLatch latch = new CountDownLatch(count) diff --git a/java/java-tests/testSrc/com/intellij/psi/TypesTest.java b/java/java-tests/testSrc/com/intellij/psi/TypesTest.java index 1ae10fadaeb1..1613f6344e08 100644 --- a/java/java-tests/testSrc/com/intellij/psi/TypesTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/TypesTest.java @@ -454,6 +454,6 @@ public class TypesTest extends GenericsTestCase { assertEquals(PsiType.INT, plusBytePrefix.getType()); final PsiStatement declaration = factory.createStatementFromText("Byte b = 1;", null); final PsiExpression plusPlusPostfix = factory.createExpressionFromText("b++", declaration); - assertEquals(PsiType.BYTE, plusPlusPostfix.getType()); + assertEquals(PsiType.BYTE.getBoxedType(declaration), plusPlusPostfix.getType()); } } diff --git a/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveInLibrariesTest.groovy b/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveInLibrariesTest.groovy index 2c24ba632bb7..36d6b534c67d 100644 --- a/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveInLibrariesTest.groovy +++ b/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveInLibrariesTest.groovy @@ -131,8 +131,8 @@ class ResolveInLibrariesTest extends JavaCodeInsightFixtureTestCase { assert fooInheritors(m1) == [fooMethod(other0), fooMethod(b1)] as Set } - private PsiMethod fooMethod(PsiClass c) { c.findMethodsByName('foo', false)[0] } - private Set<PsiMethod> fooInheritors(PsiClass c) { OverridingMethodsSearch.search(fooMethod(c)).findAll() as Set } + private static PsiMethod fooMethod(PsiClass c) { c.findMethodsByName('foo', false)[0] } + private static Set<PsiMethod> fooInheritors(PsiClass c) { OverridingMethodsSearch.search(fooMethod(c)).findAll() as Set } public void "test do not parse not stubbed sources in class jars"() { def lib = LocalFileSystem.getInstance().refreshAndFindFileByPath(PathManagerEx.getTestDataPath() + "/libResolve/classesAndSources") @@ -150,6 +150,9 @@ class ResolveInLibrariesTest extends JavaCodeInsightFixtureTestCase { Collection<VirtualFile> pkgChildren = pkgDirs.collect { it.children as List }.flatten() PsiFile javaSrc = psiManager.findFile(pkgChildren.find { it.name == 'LibraryClass.java' }) assert !javaSrc.node.parsed + + assert pkg.containsClassNamed('LibraryClass') + assert !javaSrc.node.parsed } } diff --git a/java/java-tests/testSrc/com/intellij/psi/search/UpdateCacheTest.java b/java/java-tests/testSrc/com/intellij/psi/search/UpdateCacheTest.java index 01fb2d1e512e..fe43ca04330e 100644 --- a/java/java-tests/testSrc/com/intellij/psi/search/UpdateCacheTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/search/UpdateCacheTest.java @@ -19,13 +19,13 @@ import com.intellij.JavaTestUtil; import com.intellij.ide.highlighter.JavaFileType; import com.intellij.ide.impl.ProjectUtil; import com.intellij.ide.todo.TodoConfiguration; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.projectRoots.impl.ProjectRootUtil; -import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.ex.ProjectRootManagerEx; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -284,26 +284,7 @@ public class UpdateCacheTest extends PsiTestCase{ PsiTodoSearchHelper.SERVICE.getInstance(myProject).findFilesWithTodoItems(); // to update caches - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - final ModifiableRootModel rootModel1 = ModuleRootManager.getInstance(myModule).getModifiableModel(); - final ContentEntry[] content1 = rootModel1.getContentEntries(); - contentLoop: - for (ContentEntry contentEntry : content1) { - if (root.equals(contentEntry.getFile())) { - final ExcludeFolder[] excludeFolders = contentEntry.getExcludeFolders(); - for (ExcludeFolder excludeFolder : excludeFolders) { - if (dir.equals(excludeFolder.getFile())) { - contentEntry.removeExcludeFolder(excludeFolder); - break contentLoop; - } - } - } - } - rootModel1.commit(); - } - }); - + PsiTestUtil.removeExcludedRoot(myModule, dir); PsiClass exceptionClass = myJavaFacade.findClass("java.lang.Exception", GlobalSearchScope.allScope(getProject())); assertNotNull(exceptionClass); @@ -338,9 +319,8 @@ public class UpdateCacheTest extends PsiTestCase{ checkTodos(new String[]{"2.java", "New.java"}); } - public void testRemoveSourceRoot() throws Exception{ - final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule); - final VirtualFile root = rootManager.getContentRoots()[0]; + public void testRemoveSourceRoot() { + final VirtualFile root = ModuleRootManager.getInstance(myModule).getContentRoots()[0]; PsiTodoSearchHelper.SERVICE.getInstance(myProject).findFilesWithTodoItems(); // to initialize caches @@ -356,27 +336,9 @@ public class UpdateCacheTest extends PsiTestCase{ PsiTodoSearchHelper.SERVICE.getInstance(myProject).findFilesWithTodoItems(); // to update caches - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - VirtualFile[] sourceRoots = rootManager.getSourceRoots(); - LOG.assertTrue(sourceRoots.length == 1); - final ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel(); - final ContentEntry[] content1 = rootModel.getContentEntries(); - contentLoop: - for (ContentEntry contentEntry : content1) { - if (root.equals(contentEntry.getFile())) { - final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); - for (SourceFolder sourceFolder : sourceFolders) { - if (sourceRoots[0].equals(sourceFolder.getFile())) { - contentEntry.removeSourceFolder(sourceFolder); - break contentLoop; - } - } - } - } - rootModel.commit(); - } - }); + VirtualFile[] sourceRoots = ModuleRootManager.getInstance(myModule).getSourceRoots(); + LOG.assertTrue(sourceRoots.length == 1); + PsiTestUtil.removeSourceRoot(myModule, sourceRoots[0]); PsiClass exceptionClass = myJavaFacade.findClass("java.lang.Exception", GlobalSearchScope.allScope(getProject())); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameLocalTest.java b/java/java-tests/testSrc/com/intellij/refactoring/RenameLocalTest.java index a57526b3e9ba..c254828e4d36 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/RenameLocalTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameLocalTest.java @@ -109,6 +109,10 @@ public class RenameLocalTest extends LightRefactoringTestCase { doTestInplaceRename("r1"); } + public void testRenameToFieldNameInStaticContext() throws Exception { + doTestInplaceRename("myFoo"); + } + public void testRenameInPlaceInStaticContextWithConflictingField() throws Exception { doTestInplaceRename("s"); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java index 0fff5440c057..a157129cbe4e 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java @@ -4,6 +4,7 @@ import com.intellij.JavaTestUtil; import com.intellij.codeInsight.TargetElementUtilBase; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; +import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiLocalVariable; import com.intellij.psi.PsiReference; @@ -221,6 +222,7 @@ public class InlineLocalTest extends LightCodeInsightTestCase { private void doTest(final boolean inlineDef) throws Exception { + setLanguageLevel(LanguageLevel.JDK_1_7); String name = getTestName(false); String fileName = "/refactoring/inlineLocal/" + name + ".java"; configureByFile(fileName); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java index 98a2685d5575..b29fe84bc2c4 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java @@ -17,6 +17,7 @@ package com.intellij.refactoring.inline; import com.intellij.JavaTestUtil; import com.intellij.codeInsight.TargetElementUtilBase; +import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiReference; @@ -158,6 +159,7 @@ public class InlineMethodTest extends LightRefactoringTestCase { } public void testInferredType() throws Exception { + setLanguageLevel(LanguageLevel.JDK_1_7); doTest(); } diff --git a/java/jdkAnnotations/java/net/annotations.xml b/java/jdkAnnotations/java/net/annotations.xml index 80883c8fdf23..ccc7e1640069 100644 --- a/java/jdkAnnotations/java/net/annotations.xml +++ b/java/jdkAnnotations/java/net/annotations.xml @@ -6,6 +6,9 @@ <item name="java.net.URL URL(java.lang.String, java.lang.String, java.lang.String) 0"> <annotation name="org.jetbrains.annotations.NonNls" /> </item> + <item name="java.net.URL URL(java.net.URL, java.lang.String) 1"> + <annotation name="org.jetbrains.annotations.NonNls" /> + </item> <item name="java.net.URLConnection java.lang.String getHeaderField(java.lang.String) 0"> <annotation name="org.jetbrains.annotations.NonNls" /> </item> diff --git a/java/jdkAnnotations/javax/swing/plaf/basic/annotations.xml b/java/jdkAnnotations/javax/swing/plaf/basic/annotations.xml index 6985721e60ec..420b4dcf6c75 100644 --- a/java/jdkAnnotations/javax/swing/plaf/basic/annotations.xml +++ b/java/jdkAnnotations/javax/swing/plaf/basic/annotations.xml @@ -1,33 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> <root> - <item name='javax.swing.plaf.basic.BasicArrowButton void setDirection(int) 0'> - <annotation name='org.intellij.lang.annotations.MagicConstant'> - <val name="intValues" val="{javax.swing.SwingConstants.NORTH,javax.swing.SwingConstants.SOUTH,javax.swing.SwingConstants.EAST,javax.swing.SwingConstants.WEST}"/> + <item name="javax.swing.plaf.basic.BasicArrowButton BasicArrowButton(int) 0"> + <annotation name="org.intellij.lang.annotations.MagicConstant"> + <val name="intValues" val="{javax.swing.SwingConstants.NORTH,javax.swing.SwingConstants.SOUTH,javax.swing.SwingConstants.EAST,javax.swing.SwingConstants.WEST}" /> </annotation> </item> - <item name='javax.swing.plaf.basic.BasicArrowButton void getDirection()'> - <annotation name='org.intellij.lang.annotations.MagicConstant'> - <val name="intValues" val="{javax.swing.SwingConstants.NORTH,javax.swing.SwingConstants.SOUTH,javax.swing.SwingConstants.EAST,javax.swing.SwingConstants.WEST}"/> + <item name="javax.swing.plaf.basic.BasicArrowButton BasicArrowButton(int, java.awt.Color, java.awt.Color, java.awt.Color, java.awt.Color) 0"> + <annotation name="org.intellij.lang.annotations.MagicConstant"> + <val name="intValues" val="{javax.swing.SwingConstants.NORTH,javax.swing.SwingConstants.SOUTH,javax.swing.SwingConstants.EAST,javax.swing.SwingConstants.WEST}" /> </annotation> </item> - <item - name='javax.swing.plaf.basic.BasicArrowButton BasicArrowButton(int, java.awt.Color, java.awt.Color, java.awt.Color, java.awt.Color) 0'> - <annotation name='org.intellij.lang.annotations.MagicConstant'> - <val name="intValues" val="{javax.swing.SwingConstants.NORTH,javax.swing.SwingConstants.SOUTH,javax.swing.SwingConstants.EAST,javax.swing.SwingConstants.WEST}"/> + <item name="javax.swing.plaf.basic.BasicArrowButton void getDirection()"> + <annotation name="org.intellij.lang.annotations.MagicConstant"> + <val name="intValues" val="{javax.swing.SwingConstants.NORTH,javax.swing.SwingConstants.SOUTH,javax.swing.SwingConstants.EAST,javax.swing.SwingConstants.WEST}" /> </annotation> </item> - <item name='javax.swing.plaf.basic.BasicArrowButton BasicArrowButton(int) 0'> - <annotation name='org.intellij.lang.annotations.MagicConstant'> - <val name="intValues" val="{javax.swing.SwingConstants.NORTH,javax.swing.SwingConstants.SOUTH,javax.swing.SwingConstants.EAST,javax.swing.SwingConstants.WEST}"/> + <item name="javax.swing.plaf.basic.BasicArrowButton void setDirection(int) 0"> + <annotation name="org.intellij.lang.annotations.MagicConstant"> + <val name="intValues" val="{javax.swing.SwingConstants.NORTH,javax.swing.SwingConstants.SOUTH,javax.swing.SwingConstants.EAST,javax.swing.SwingConstants.WEST}" /> </annotation> </item> - <item name='javax.swing.plaf.basic.BasicScrollBarUI javax.swing.JButton createDecreaseButton(int) 0'> - <annotation name='org.intellij.lang.annotations.MagicConstant'> - <val name="intValues" val="{javax.swing.SwingConstants.NORTH,javax.swing.SwingConstants.SOUTH,javax.swing.SwingConstants.EAST,javax.swing.SwingConstants.WEST}"/> + <item name="javax.swing.plaf.basic.BasicScrollBarUI javax.swing.JButton createDecreaseButton(int) 0"> + <annotation name="org.intellij.lang.annotations.MagicConstant"> + <val name="intValues" val="{javax.swing.SwingConstants.NORTH,javax.swing.SwingConstants.SOUTH,javax.swing.SwingConstants.EAST,javax.swing.SwingConstants.WEST}" /> </annotation> </item> - <item name='javax.swing.plaf.basic.BasicScrollBarUI javax.swing.JButton createIncreaseButton(int) 0'> - <annotation name='org.intellij.lang.annotations.MagicConstant'> - <val name="intValues" val="{javax.swing.SwingConstants.NORTH,javax.swing.SwingConstants.SOUTH,javax.swing.SwingConstants.EAST,javax.swing.SwingConstants.WEST}"/> + <item name="javax.swing.plaf.basic.BasicScrollBarUI javax.swing.JButton createIncreaseButton(int) 0"> + <annotation name="org.intellij.lang.annotations.MagicConstant"> + <val name="intValues" val="{javax.swing.SwingConstants.NORTH,javax.swing.SwingConstants.SOUTH,javax.swing.SwingConstants.EAST,javax.swing.SwingConstants.WEST}" /> </annotation> </item> -</root>
\ No newline at end of file +</root> + diff --git a/java/jdkAnnotations/javax/swing/tree/annotations.xml b/java/jdkAnnotations/javax/swing/tree/annotations.xml index 20f818503be0..055cc92a5500 100644 --- a/java/jdkAnnotations/javax/swing/tree/annotations.xml +++ b/java/jdkAnnotations/javax/swing/tree/annotations.xml @@ -1,5 +1,20 @@ <?xml version="1.0" encoding="UTF-8"?> <root> + <item name="javax.swing.tree.TreePath TreePath(java.lang.Object) 0"> + <annotation name="org.jetbrains.annotations.NotNull" /> + </item> + <item name="javax.swing.tree.TreePath TreePath(java.lang.Object[]) 0"> + <annotation name="org.jetbrains.annotations.NotNull" /> + </item> + <item name="javax.swing.tree.TreePath TreePath(java.lang.Object[], int) 0"> + <annotation name="org.jetbrains.annotations.NotNull" /> + </item> + <item name="javax.swing.tree.TreePath TreePath(javax.swing.tree.TreePath, java.lang.Object) 1"> + <annotation name="org.jetbrains.annotations.NotNull" /> + </item> + <item name="javax.swing.tree.TreePath javax.swing.tree.TreePath pathByAddingChild(java.lang.Object) 0"> + <annotation name="org.jetbrains.annotations.NotNull" /> + </item> <item name="javax.swing.tree.TreeSelectionModel int getSelectionMode()"> <annotation name="org.intellij.lang.annotations.MagicConstant"> <val name="valuesFromClass" val="javax.swing.tree.TreeSelectionModel.class" /> diff --git a/java/jsp-base-openapi/src/com/intellij/lang/jsp/IBaseJspManager.java b/java/jsp-base-openapi/src/com/intellij/lang/jsp/IBaseJspManager.java index a7fabc4e3bf5..1c216355b257 100644 --- a/java/jsp-base-openapi/src/com/intellij/lang/jsp/IBaseJspManager.java +++ b/java/jsp-base-openapi/src/com/intellij/lang/jsp/IBaseJspManager.java @@ -29,4 +29,6 @@ public interface IBaseJspManager { @Nullable XmlElementDescriptor getDirectiveDescriptorByName(String name, @NotNull PsiFile context); + + boolean isElIgnored(@NotNull PsiFile file); } diff --git a/java/jsp-spi/src/com/intellij/psi/impl/source/jsp/JspManager.java b/java/jsp-spi/src/com/intellij/psi/impl/source/jsp/JspManager.java index 3b93049b5e9b..46d04cde530f 100644 --- a/java/jsp-spi/src/com/intellij/psi/impl/source/jsp/JspManager.java +++ b/java/jsp-spi/src/com/intellij/psi/impl/source/jsp/JspManager.java @@ -17,13 +17,10 @@ package com.intellij.psi.impl.source.jsp; import com.intellij.lang.jsp.IBaseJspManager; import com.intellij.lang.jsp.JspVersion; +import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.components.ServiceManager; -import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileSystemItem; import com.intellij.psi.jsp.JspFile; import com.intellij.psi.xml.XmlFile; diff --git a/java/mockJDK-1.7/jre/lib/rt.jar b/java/mockJDK-1.7/jre/lib/rt.jar Binary files differindex f2c43d2be6e6..797d0c1b7551 100644 --- a/java/mockJDK-1.7/jre/lib/rt.jar +++ b/java/mockJDK-1.7/jre/lib/rt.jar diff --git a/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java b/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java index b440e4cef490..e06b22ab9027 100644 --- a/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java +++ b/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java @@ -50,9 +50,15 @@ public class CodeInsightServicesUtil { expression.getTokenBeforeOperand(op).replace(createOperationToken(factory, ourTokenMap[i + (i % 2 == 0 ? 1 : -1)])); } if (tokenType == JavaTokenType.OROR || tokenType == JavaTokenType.ANDAND) { - op.replace(invertCondition(op)); + PsiExpression inverted = invertCondition(op); + op.replace(inverted); } } + if (tokenType == JavaTokenType.ANDAND && booleanExpression.getParent() instanceof PsiExpression) { + final PsiParenthesizedExpression parth = (PsiParenthesizedExpression)factory.createExpressionFromText("(a)", expression); + parth.getExpression().replace(expression); + return parth; + } return expression; } } diff --git a/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java b/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java index cd3fed795f8a..e8afbc66751e 100644 --- a/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java +++ b/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java @@ -22,6 +22,7 @@ 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.NotNull; import org.jetbrains.annotations.Nullable; public class BaseGenerateAction extends CodeInsightAction { @@ -31,6 +32,7 @@ public class BaseGenerateAction extends CodeInsightAction { myHandler = handler; } + @NotNull @Override protected final CodeInsightActionHandler getHandler() { return myHandler; @@ -46,7 +48,7 @@ public class BaseGenerateAction extends CodeInsightAction { } @Override - protected boolean isValidForFile(Project project, Editor editor, PsiFile file) { + protected boolean isValidForFile(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { if (!(file instanceof PsiJavaFile)) return false; if (file instanceof PsiCompiledElement) return false; diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileContainer.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileContainer.java index adfd415dfa2d..40d748b0c634 100644 --- a/java/openapi/src/com/intellij/util/descriptors/ConfigFileContainer.java +++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileContainer.java @@ -18,12 +18,13 @@ package com.intellij.util.descriptors; import com.intellij.openapi.project.Project; import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.ModificationTracker; import org.jetbrains.annotations.Nullable; /** * @author nik */ -public interface ConfigFileContainer extends Disposable { +public interface ConfigFileContainer extends Disposable, ModificationTracker { Project getProject(); void addListener(ConfigFileListener listener, Disposable parentDisposable); diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java index 2cc216d4a460..206e65d420a2 100644 --- a/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java @@ -32,6 +32,7 @@ import com.intellij.testFramework.HighlightTestInfo; import com.intellij.testFramework.LightCodeInsightTestCase; import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl; import com.intellij.util.ArrayUtil; +import gnu.trove.TIntArrayList; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -139,7 +140,14 @@ public abstract class LightDaemonAnalyzerTestCase extends LightCodeInsightTestCa protected List<HighlightInfo> doHighlighting() { PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); - int[] toIgnore = doFolding() ? ArrayUtil.EMPTY_INT_ARRAY : new int[]{Pass.UPDATE_FOLDING}; + TIntArrayList toIgnoreList = new TIntArrayList(); + if (!doFolding()) { + toIgnoreList.add(Pass.UPDATE_FOLDING); + } + if (!doInspections()) { + toIgnoreList.add(Pass.LOCAL_INSPECTIONS); + } + int[] toIgnore = toIgnoreList.isEmpty() ? ArrayUtil.EMPTY_INT_ARRAY : toIgnoreList.toNativeArray(); Editor editor = getEditor(); PsiFile file = getFile(); if (editor instanceof EditorWindow) { @@ -157,4 +165,8 @@ public abstract class LightDaemonAnalyzerTestCase extends LightCodeInsightTestCa protected boolean doFolding() { return false; } + + protected boolean doInspections() { + return true; + } } diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java index 9cf1c202a7d8..cf95fb2560e4 100644 --- a/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -49,8 +49,12 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static com.intellij.util.ObjectUtils.notNull; + public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase { @NonNls private static final String BEFORE_PREFIX = "before"; + @NonNls private static final String AFTER_PREFIX = "after"; + private static QuickFixTestCase myWrapper; protected boolean shouldBeAvailableAfterExecution() { @@ -62,10 +66,11 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase } private static void doTestFor(final String testName, final QuickFixTestCase quickFixTestCase) { - final String relativePath = quickFixTestCase.getBasePath() + "/" + BEFORE_PREFIX + testName; + final String relativePath = notNull(quickFixTestCase.getBasePath(), "") + "/" + BEFORE_PREFIX + testName; final String testFullPath = quickFixTestCase.getTestDataPath().replace(File.separatorChar, '/') + relativePath; final File testFile = new File(testFullPath); CommandProcessor.getInstance().executeCommand(quickFixTestCase.getProject(), new Runnable() { + @SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod", "CallToPrintStackTrace"}) @Override public void run() { try { @@ -118,6 +123,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase } // "quick fix action text to perform" "should be available" + assert comment != null : commenter; Pattern pattern = Pattern.compile("^" + comment.replace("*", "\\*") + actionPattern, Pattern.DOTALL); Matcher matcher = pattern.matcher(contents); assertTrue("No comment found in "+file.getVirtualFile(), matcher.matches()); @@ -126,10 +132,11 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase return Pair.create(text, actionShouldBeAvailable); } - @SuppressWarnings({"HardCodedStringLiteral"}) - public static void doAction(final String text, final boolean actionShouldBeAvailable, final String testFullPath, final String testName, - QuickFixTestCase quickFix) - throws Exception { + public static void doAction(String text, + boolean actionShouldBeAvailable, + String testFullPath, + String testName, + QuickFixTestCase quickFix) throws Exception { IntentionAction action = quickFix.findActionWithText(text); if (action == null) { if (actionShouldBeAvailable) { @@ -139,7 +146,8 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase texts.add(intentionAction.getText()); } Collection<HighlightInfo> infos = quickFix.doHighlighting(); - fail("Action with text '" + text + "' is not available in test " + testFullPath+"\nAvailable actions ("+texts.size()+"): "+texts+"\n"+actions+"\nInfos:"+infos); + fail("Action with text '" + text + "' is not available in test " + testFullPath + "\n" + + "Available actions (" + texts.size() + "): " + texts + "\n" + actions + "\nInfos:" + infos); } } else { @@ -155,7 +163,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase fail("Action '" + text + "' is still available after its invocation in test " + testFullPath); } } - final String expectedFilePath = quickFix.getBasePath() + "/after" + testName; + String expectedFilePath = notNull(quickFix.getBasePath(), "") + "/" + AFTER_PREFIX + testName; quickFix.checkResultByFile("In file :" + expectedFilePath, expectedFilePath, false); } } @@ -208,7 +216,6 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase for (File file : files) { final String testName = file.getName().substring(BEFORE_PREFIX.length()); doTestFor(testName, testCase); - System.out.println(file.getPath()); } assertTrue("Test files not found in "+testDirPath,files.length != 0); } |