Merge "Merge remote-tracking branch 'aosp/snapshot-master' into merge"
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
index 0b13401..d8fe919 100644
--- a/.idea/codeStyleSettings.xml
+++ b/.idea/codeStyleSettings.xml
@@ -90,9 +90,6 @@
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
- <ADDITIONAL_INDENT_OPTIONS fileType="rb">
- <option name="INDENT_SIZE" value="2" />
- </ADDITIONAL_INDENT_OPTIONS>
<codeStyleSettings language="CFML">
<option name="KEEP_LINE_BREAKS" value="false" />
<option name="ELSE_ON_NEW_LINE" value="true" />
@@ -265,6 +262,15 @@
<option name="TAB_SIZE" value="8" />
</indentOptions>
</codeStyleSettings>
+ <codeStyleSettings language="ruby">
+ <option name="KEEP_LINE_BREAKS" value="false" />
+ <option name="PARENT_SETTINGS_INSTALLED" value="true" />
+ <indentOptions>
+ <option name="CONTINUATION_INDENT_SIZE" value="8" />
+ <option name="TAB_SIZE" value="4" />
+ <option name="USE_RELATIVE_INDENTS" value="false" />
+ </indentOptions>
+ </codeStyleSettings>
</value>
</option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 25d4282..0e88b0f 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -26,6 +26,7 @@
</profile>
</annotationProcessing>
<bytecodeTargetLevel target="1.6">
+ <module name="annotations" target="1.5" />
<module name="groovy-rt-constants" target="1.5" />
<module name="groovy_rt" target="1.5" />
<module name="java-runtime" target="1.3" />
diff --git a/.idea/libraries/Netty.xml b/.idea/libraries/Netty.xml
index 7cbf9804..3fbc531 100644
--- a/.idea/libraries/Netty.xml
+++ b/.idea/libraries/Netty.xml
@@ -1,11 +1,11 @@
<component name="libraryTable">
<library name="Netty">
<CLASSES>
- <root url="jar://$PROJECT_DIR$/lib/netty-3.6.6.Final.jar!/" />
+ <root url="jar://$PROJECT_DIR$/lib/netty-all.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
- <root url="jar://$PROJECT_DIR$/lib/src/netty-3.6.6.Final-sources.jar!/" />
+ <root url="jar://$PROJECT_DIR$/lib/src/netty-all-sources.jar!/" />
</SOURCES>
</library>
</component>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 33ad474..dfa52fc 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -116,6 +116,7 @@
<module fileurl="file://$PROJECT_DIR$/../base/lint/cli/lint-cli.iml" filepath="$PROJECT_DIR$/../base/lint/cli/lint-cli.iml" group="plugins/Android/android-sdk/lint" />
<module fileurl="file://$PROJECT_DIR$/platform/lvcs-api/lvcs-api.iml" filepath="$PROJECT_DIR$/platform/lvcs-api/lvcs-api.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/lvcs-impl/lvcs-impl.iml" filepath="$PROJECT_DIR$/platform/lvcs-impl/lvcs-impl.iml" group="platform" />
+ <module fileurl="file://$PROJECT_DIR$/java/manifest/manifest.iml" filepath="$PROJECT_DIR$/java/manifest/manifest.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/../base/manifest-merger/manifest-merger.iml" filepath="$PROJECT_DIR$/../base/manifest-merger/manifest-merger.iml" group="plugins/Android/android-sdk" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven.iml" filepath="$PROJECT_DIR$/plugins/maven/maven.iml" group="plugins/maven" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/artifact-resolver-m2/maven-artifact-resolver-m2.iml" filepath="$PROJECT_DIR$/plugins/maven/artifact-resolver-m2/maven-artifact-resolver-m2.iml" group="plugins/maven" />
@@ -138,6 +139,7 @@
<module fileurl="file://$PROJECT_DIR$/xml/relaxng/relaxng.iml" filepath="$PROJECT_DIR$/xml/relaxng/relaxng.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/platform/remote-servers/api/remote-servers-api.iml" filepath="$PROJECT_DIR$/platform/remote-servers/api/remote-servers-api.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/remote-servers/impl/remote-servers-impl.iml" filepath="$PROJECT_DIR$/platform/remote-servers/impl/remote-servers-impl.iml" group="platform" />
+ <module fileurl="file://$PROJECT_DIR$/java/remote-servers/remote-servers-java.iml" filepath="$PROJECT_DIR$/java/remote-servers/remote-servers-java.iml" />
<module fileurl="file://$PROJECT_DIR$/resources/resources.iml" filepath="$PROJECT_DIR$/resources/resources.iml" />
<module fileurl="file://$PROJECT_DIR$/resources-en/resources-en.iml" filepath="$PROJECT_DIR$/resources-en/resources-en.iml" />
<module fileurl="file://$PROJECT_DIR$/../base/sdk-common/sdk-common.iml" filepath="$PROJECT_DIR$/../base/sdk-common/sdk-common.iml" group="plugins/Android/android-sdk" />
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
index cb8806f..ec8ce05 100644
--- a/.idea/uiDesigner.xml
+++ b/.idea/uiDesigner.xml
@@ -138,9 +138,6 @@
<item class="com.intellij.ui.ReferenceEditorComboWithBrowseButton" icon="/com/intellij/uiDesigner/icons/panel.png" removable="true" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="7" anchor="0" fill="1" />
</item>
- <item class="com.intellij.ui.HyperlinkLabel" icon="" removable="true" auto-create-binding="false" can-attach-label="false">
- <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="0" />
- </item>
</group>
</component>
<component name="uidesigner-configuration">
diff --git a/build/conf/classVersions.txt b/build/conf/classVersions.txt
index f2a055b..7ccac5c 100644
--- a/build/conf/classVersions.txt
+++ b/build/conf/classVersions.txt
@@ -31,7 +31,8 @@
1.3 => lib/idea_rt.jar
1.7 => lib/fxHelpBrowser.jar
-- => lib/optimizedFileManager.jar
+1.7 => lib/optimizedFileManager.jar
1.5 => plugins/Groovy/lib/groovy_rt.jar
+1.5 => lib/annotations.jar
diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant
index b7475ea..37504c4 100644
--- a/build/scripts/layouts.gant
+++ b/build/scripts/layouts.gant
@@ -66,6 +66,7 @@
List<String> implementationModules = [platformImplementationModules,
"compiler-impl",
"remote-servers-impl",
+ "remote-servers-java",
"debugger-impl",
"dom-impl",
"execution-impl",
@@ -77,10 +78,10 @@
"java-impl",
"java-psi-impl",
"jsp-spi",
+ "manifest",
"platform-main",
"testFramework",
- "tests_bootstrap",
- ].flatten()
+ "tests_bootstrap"].flatten()
ant.patternset(id: "resources.included") {
include(name: "**/*.properties")
@@ -466,6 +467,11 @@
}
fileset(dir: "$home/plugins/terminal/lib") {
include(name: "*.jar")
+ include(name: "*.in")
+ include(name: "**/*.dll")
+ include(name: "**/*.exe")
+ include(name: "**/*.dylib")
+ include(name: "**/*.so")
}
}
}
diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant
index c099600..b4fd69a 100644
--- a/build/scripts/libLicenses.gant
+++ b/build/scripts/libLicenses.gant
@@ -248,7 +248,7 @@
libraryLicense(name: "XStream", version: "1.4.3", license: "BSD", url: "http://xstream.codehaus.org/", licenseUrl: "http://xstream.codehaus.org/license.html")
libraryLicense(name: "YourKit Java Profiler", libraryName: "yjp-controller-api-redist.jar", version: "8.0.x", license: "link (commercial license)", url: "http://yourkit.com/", licenseUrl: "http://www.yourkit.com/purchase/license.html")
libraryLicense(name: "protobuf", version: "2.5.0", license: "New BSD", url: "http://code.google.com/p/protobuf/", licenseUrl: "http://code.google.com/p/protobuf/source/browse/trunk/COPYING.txt?r=367")
-libraryLicense(name: "Netty", libraryName: "Netty", version: "3.6.6", license: "Apache 2.0", url: "http://netty.io", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
+libraryLicense(name: "Netty", libraryName: "Netty", version: "4.0.8-SNAPSHOT", license: "Apache 2.0", url: "http://netty.io", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Kryo", libraryName: "Kryo", version: "1.04", license: "New BSD License", url: "http://code.google.com/p/kryo/", licenseUrl: "http://www.opensource.org/licenses/bsd-license.php")
libraryLicense(name: "Snappy-Java", libraryName: "Snappy-Java", version: "1.0.5", license: "Apache 2.0", url: "http://code.google.com/p/snappy-java/", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Cucumber-Java", libraryName: "cucumber-java", version: "1.0.14", license: "MIT License", url: "https://github.com/cucumber/cucumber-jvm/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html")
@@ -265,6 +265,8 @@
libraryLicense(name: "bouncy-castle", version: "1.48", license: "MIT License", url: "http://bouncycastle.org", licenseUrl: "http://bouncycastle.org/licence.html")
libraryLicense(name: "kXML2", libraryName: "kxml2", version: "2.3.0", license: "BSD", url: "http://sourceforge.net/projects/kxml/")
libraryLicense(name: "Lombok AST", libraryName: "lombok-ast", version: "0.2.1", license: "MIT", url: "http://projectlombok.org/", licenseUrl: "http://opensource.org/licenses/mit-license.php")
+libraryLicense(name: "json-path", libraryName: "json-path-0.8.0.jar", version: "0.8.0", license: "Apache 2.0", url: "http://code.google.com/p/json-path/", licenseUrl: "http://apache.org/licenses/LICENSE-2.0")
+libraryLicense(name: "json-smart", libraryName: "json-smart-1.1.1.jar", version: "1.1.1", license: "Apache 2.0", url: "http://code.google.com/p/json-smart/", licenseUrl: "http://apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "fxg-utils", libraryName: "fxg-utils", version: "4.9.1", license: "Apache 2.0", url: "http://flex.apache.org", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "jayatana", libraryName: "jayatana", version: "1.2.4", license: "MIT License", url: "https://code.google.com/p/java-swing-ayatana/", licenseUrl: "http://opensource.org/licenses/mit-license.php")
jetbrainsLibrary("JPS")
diff --git a/community-main.iml b/community-main.iml
index 9e92fe4..06e2a0a 100644
--- a/community-main.iml
+++ b/community-main.iml
@@ -61,11 +61,8 @@
<orderEntry type="module" module-name="ui-designer" />
<orderEntry type="module" module-name="devkit" />
<orderEntry type="module" module-name="eclipse" />
- <orderEntry type="module" module-name="generate-tostring" />
<orderEntry type="module" module-name="git4idea" />
<orderEntry type="module" module-name="images" />
- <orderEntry type="module" module-name="InspectionGadgetsPlugin" />
- <orderEntry type="module" module-name="IntentionPowerPackPlugin" />
<orderEntry type="module" module-name="jetgroovy" />
<orderEntry type="module" module-name="junit" />
<orderEntry type="module" module-name="maven" />
@@ -91,16 +88,17 @@
<orderEntry type="module" module-name="relaxng" />
<orderEntry type="module" module-name="gradle" />
<orderEntry type="module" module-name="remote-servers-impl" />
- <orderEntry type="module" module-name="xml-tests" scope="TEST" />
<orderEntry type="module" module-name="dom-tests" />
- <orderEntry type="module" module-name="devkit-jps-plugin" scope="TEST" />
- <orderEntry type="module" module-name="ui-designer-jps-plugin" scope="TEST" />
<orderEntry type="module" module-name="colorSchemes" />
<orderEntry type="module" module-name="javaFX-CE" />
<orderEntry type="module" module-name="javaFX-jps-plugin" />
+ <orderEntry type="module" module-name="IntelliLang-tests" />
+ <orderEntry type="module" module-name="manifest" />
+ <orderEntry type="module" module-name="xml-tests" scope="TEST" />
+ <orderEntry type="module" module-name="devkit-jps-plugin" scope="TEST" />
+ <orderEntry type="module" module-name="ui-designer-jps-plugin" scope="TEST" />
<orderEntry type="module" module-name="java-tests" scope="TEST" />
<orderEntry type="module" module-name="community-tests" scope="TEST" />
- <orderEntry type="module" module-name="IntelliLang-tests" />
</component>
</module>
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java
index 27f61c4..810ce71 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java
@@ -47,7 +47,7 @@
private static final String PROBLEMS_TOOLWINDOW_ID = "Problems";
private final ProblemsViewPanel myPanel;
- private final SequentialTaskExecutor myViewUpdater = new SequentialTaskExecutor(new PooledThreadExecutor());
+ private final SequentialTaskExecutor myViewUpdater = new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE);
public ProblemsViewImpl(final Project project, final ToolWindowManager wm) {
super(project);
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 e885a16..1db0ada 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
@@ -80,20 +80,20 @@
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.net.NetUtils;
import gnu.trove.THashSet;
-import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.*;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.channel.group.ChannelGroupFuture;
-import org.jboss.netty.channel.group.DefaultChannelGroup;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
-import org.jboss.netty.handler.codec.protobuf.ProtobufDecoder;
-import org.jboss.netty.handler.codec.protobuf.ProtobufEncoder;
-import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
-import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.handler.codec.protobuf.ProtobufDecoder;
+import io.netty.handler.codec.protobuf.ProtobufEncoder;
+import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
+import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.ide.PooledThreadExecutor;
+import org.jetbrains.io.ChannelRegistrar;
+import org.jetbrains.io.NettyUtil;
import org.jetbrains.jps.api.*;
import org.jetbrains.jps.cmdline.BuildMain;
import org.jetbrains.jps.cmdline.ClasspathBootstrap;
@@ -106,7 +106,6 @@
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.*;
-import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -117,7 +116,8 @@
* @author Eugene Zhuravlev
* Date: 9/6/11
*/
-public class BuildManager implements ApplicationComponent{
+public class
+ BuildManager implements ApplicationComponent{
public static final Key<Boolean> ALLOW_AUTOMAKE = Key.create("_allow_automake_when_process_is_active_");
private static final Key<String> FORCE_MODEL_LOADING_PARAMETER = Key.create(BuildParametersKeys.FORCE_MODEL_LOADING);
@@ -152,8 +152,7 @@
private final Map<RequestFuture, Project> myAutomakeFutures = new HashMap<RequestFuture, Project>();
private final Map<String, RequestFuture> myBuildsInProgress = Collections.synchronizedMap(new HashMap<String, RequestFuture>());
private final BuildProcessClasspathManager myClasspathManager = new BuildProcessClasspathManager();
- private final Executor myPooledThreadExecutor = new PooledThreadExecutor();
- private final SequentialTaskExecutor myRequestsProcessor = new SequentialTaskExecutor(myPooledThreadExecutor);
+ private final SequentialTaskExecutor myRequestsProcessor = new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE);
private final Map<String, ProjectData> myProjectDataMap = Collections.synchronizedMap(new HashMap<String, ProjectData>());
private final BuildManagerPeriodicTask myAutoMakeTask = new BuildManagerPeriodicTask() {
@@ -206,7 +205,8 @@
}
};
- private final ChannelGroup myAllOpenChannels = new DefaultChannelGroup("build-manager");
+ private final ChannelRegistrar myChannelRegistrar = new ChannelRegistrar();
+
private final BuildMessageDispatcher myMessageDispatcher = new BuildMessageDispatcher();
private volatile int myListenPort = -1;
@Nullable
@@ -354,7 +354,7 @@
final CmdlineRemoteProto.Message.ControllerMessage message =
CmdlineRemoteProto.Message.ControllerMessage.newBuilder().setType(
CmdlineRemoteProto.Message.ControllerMessage.Type.FS_EVENT).setFsEvent(data.createNextEvent()).build();
- Channels.write(channel, CmdlineProtoUtil.toMessage(sessionId, message));
+ channel.writeAndFlush(CmdlineProtoUtil.toMessage(sessionId, message));
}
}
}
@@ -574,7 +574,7 @@
synchronized (myProjectDataMap) {
ProjectData data = myProjectDataMap.get(projectPath);
if (data == null) {
- data = new ProjectData(new SequentialTaskExecutor(myPooledThreadExecutor));
+ data = new ProjectData(new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE));
myProjectDataMap.put(projectPath, data);
}
if (isRebuild) {
@@ -951,46 +951,25 @@
}
public void stopListening() {
- final ChannelGroupFuture closeFuture = myAllOpenChannels.close();
- closeFuture.awaitUninterruptibly();
+ myChannelRegistrar.close();
}
private int startListening() throws Exception {
- final ChannelFactory channelFactory = new NioServerSocketChannelFactory(myPooledThreadExecutor, myPooledThreadExecutor, 1);
- final SimpleChannelUpstreamHandler channelRegistrar = new SimpleChannelUpstreamHandler() {
+ final ServerBootstrap bootstrap = NettyUtil.nioServerBootstrap(new NioEventLoopGroup(1, PooledThreadExecutor.INSTANCE));
+ bootstrap.childHandler(new ChannelInitializer() {
@Override
- public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
- myAllOpenChannels.add(e.getChannel());
- super.channelOpen(ctx, e);
+ protected void initChannel(Channel channel) throws Exception {
+ channel.pipeline().addLast(myChannelRegistrar,
+ new ProtobufVarint32FrameDecoder(),
+ new ProtobufDecoder(CmdlineRemoteProto.Message.getDefaultInstance()),
+ new ProtobufVarint32LengthFieldPrepender(),
+ new ProtobufEncoder(),
+ myMessageDispatcher);
}
-
- @Override
- public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
- myAllOpenChannels.remove(e.getChannel());
- super.channelClosed(ctx, e);
- }
- };
- ChannelPipelineFactory pipelineFactory = new ChannelPipelineFactory() {
- @Override
- public ChannelPipeline getPipeline() throws Exception {
- return Channels.pipeline(
- channelRegistrar,
- new ProtobufVarint32FrameDecoder(),
- new ProtobufDecoder(CmdlineRemoteProto.Message.getDefaultInstance()),
- new ProtobufVarint32LengthFieldPrepender(),
- new ProtobufEncoder(),
- myMessageDispatcher
- );
- }
- };
- final ServerBootstrap bootstrap = new ServerBootstrap(channelFactory);
- bootstrap.setPipelineFactory(pipelineFactory);
- bootstrap.setOption("child.tcpNoDelay", true);
- bootstrap.setOption("child.keepAlive", true);
- final int listenPort = NetUtils.findAvailableSocketPort();
- final Channel serverChannel = bootstrap.bind(new InetSocketAddress(NetUtils.getLoopbackAddress(), listenPort));
- myAllOpenChannels.add(serverChannel);
- return listenPort;
+ });
+ Channel serverChannel = bootstrap.bind(NetUtils.getLoopbackAddress(), 0).syncUninterruptibly().channel();
+ myChannelRegistrar.add(serverChannel);
+ return ((InetSocketAddress)serverChannel.localAddress()).getPort();
}
@TestOnly
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java
index 0c49759..135b154 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java
@@ -15,10 +15,13 @@
*/
package com.intellij.compiler.server;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.containers.ConcurrentHashSet;
-import org.jboss.netty.channel.*;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.util.AttributeKey;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.api.CmdlineProtoUtil;
import org.jetbrains.jps.api.CmdlineRemoteProto;
@@ -32,8 +35,12 @@
* @author Eugene Zhuravlev
* Date: 4/25/12
*/
-class BuildMessageDispatcher extends SimpleChannelHandler {
+@ChannelHandler.Sharable
+class BuildMessageDispatcher extends SimpleChannelInboundHandler<CmdlineRemoteProto.Message> {
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.server.BuildMessageDispatcher");
+
+ private static final AttributeKey<SessionData> SESSION_DATA = new AttributeKey<SessionData>("BuildMessageDispatcher.sessionData");
+
private final Map<UUID, SessionData> myMessageHandlers = new ConcurrentHashMap<UUID, SessionData>();
private final Set<UUID> myCanceledSessions = new ConcurrentHashSet<UUID>();
@@ -54,7 +61,7 @@
if (myCanceledSessions.add(sessionId)) {
final Channel channel = getConnectedChannel(sessionId);
if (channel != null) {
- Channels.write(channel, CmdlineProtoUtil.toMessage(sessionId, CmdlineProtoUtil.createCancelCommand()));
+ channel.writeAndFlush(CmdlineProtoUtil.toMessage(sessionId, CmdlineProtoUtil.createCancelCommand()));
}
}
}
@@ -62,7 +69,7 @@
@Nullable
public Channel getConnectedChannel(final UUID sessionId) {
final Channel channel = getAssociatedChannel(sessionId);
- return channel != null && channel.isConnected()? channel : null;
+ return channel != null && channel.isActive()? channel : null;
}
@Nullable
@@ -73,10 +80,8 @@
@Override
- public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
- final CmdlineRemoteProto.Message message = (CmdlineRemoteProto.Message)e.getMessage();
-
- SessionData sessionData = (SessionData)ctx.getAttachment();
+ protected void channelRead0(ChannelHandlerContext context, CmdlineRemoteProto.Message message) throws Exception {
+ SessionData sessionData = context.attr(SESSION_DATA).get();
UUID sessionId;
if (sessionData == null) {
@@ -86,11 +91,11 @@
sessionData = myMessageHandlers.get(sessionId);
if (sessionData != null) {
- sessionData.channel = ctx.getChannel();
- ctx.setAttachment(sessionData);
+ sessionData.channel = context.channel();
+ context.attr(SESSION_DATA).set(sessionData);
}
if (myCanceledSessions.contains(sessionId)) {
- Channels.write(ctx.getChannel(), CmdlineProtoUtil.toMessage(sessionId, CmdlineProtoUtil.createCancelCommand()));
+ context.channel().writeAndFlush(CmdlineProtoUtil.toMessage(sessionId, CmdlineProtoUtil.createCancelCommand()));
}
}
else {
@@ -118,14 +123,14 @@
if (params != null) {
handler.buildStarted(sessionId);
sessionData.params = null;
- Channels.write(ctx.getChannel(), CmdlineProtoUtil.toMessage(sessionId, params));
+ context.writeAndFlush(CmdlineProtoUtil.toMessage(sessionId, params));
}
else {
cancelSession(sessionId);
}
}
else {
- handler.handleBuildMessage(ctx.getChannel(), sessionId, builderMessage);
+ handler.handleBuildMessage(context.channel(), sessionId, builderMessage);
}
break;
@@ -136,12 +141,12 @@
}
@Override
- public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+ public void channelInactive(ChannelHandlerContext context) throws Exception {
try {
- super.channelClosed(ctx, e);
+ super.channelInactive(context);
}
finally {
- final SessionData sessionData = (SessionData)ctx.getAttachment();
+ final SessionData sessionData = context.attr(SESSION_DATA).get();
if (sessionData != null) {
final BuilderMessageHandler handler = unregisterBuildMessageHandler(sessionData.sessionId);
if (handler != null) {
@@ -153,31 +158,10 @@
}
@Override
- public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
- final Throwable cause = e.getCause();
+ public void exceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
if (cause != null) {
LOG.info(cause);
}
- ctx.sendUpstream(e);
- }
-
- @Override
- public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
- try {
- super.channelDisconnected(ctx, e);
- }
- finally {
- final SessionData sessionData = (SessionData)ctx.getAttachment();
- if (sessionData != null) { // this is the context corresponding to some session
- final Channel channel = e.getChannel();
- ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
- @Override
- public void run() {
- channel.close();
- }
- });
- }
- }
}
private static final class SessionData {
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuilderMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/BuilderMessageHandler.java
index fadf63b..4681f85 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuilderMessageHandler.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuilderMessageHandler.java
@@ -15,7 +15,7 @@
*/
package com.intellij.compiler.server;
-import org.jboss.netty.channel.Channel;
+import io.netty.channel.Channel;
import org.jetbrains.jps.api.CmdlineRemoteProto;
import java.util.UUID;
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java
index 35091f7..3cb1260 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java
@@ -16,7 +16,7 @@
package com.intellij.compiler.server;
import com.intellij.compiler.make.CachingSearcher;
-import com.intellij.lang.StdLanguages;
+import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
@@ -30,8 +30,7 @@
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.cls.ClsUtil;
import com.intellij.util.concurrency.SequentialTaskExecutor;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.Channels;
+import io.netty.channel.Channel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.ide.PooledThreadExecutor;
@@ -50,7 +49,7 @@
private final Project myProject;
private int myConstantSearchesCount = 0;
private final CachingSearcher mySearcher;
- private final SequentialTaskExecutor myTaskExecutor = new SequentialTaskExecutor(new PooledThreadExecutor());
+ private final SequentialTaskExecutor myTaskExecutor = new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE);
protected DefaultMessageHandler(Project project) {
myProject = project;
@@ -102,6 +101,7 @@
}
else {
ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
public void run() {
try {
String qualifiedName = ownerClassName.replace('$', '.');
@@ -137,8 +137,8 @@
continue;
}
foundAtLeastOne = true;
- final boolean sucess = performChangedConstantSearch(aClass, changedField, accessFlags, accessChanged, affectedPaths);
- if (!sucess) {
+ final boolean success = performChangedConstantSearch(aClass, changedField, accessFlags, accessChanged, affectedPaths);
+ if (!success) {
isSuccess.set(Boolean.FALSE);
break;
}
@@ -175,7 +175,7 @@
builder.setIsSuccess(false);
LOG.debug("Constant search task: unsuccessful");
}
- Channels.write(channel, CmdlineProtoUtil.toMessage(sessionId, CmdlineRemoteProto.Message.ControllerMessage.newBuilder().setType(
+ channel.writeAndFlush(CmdlineProtoUtil.toMessage(sessionId, CmdlineRemoteProto.Message.ControllerMessage.newBuilder().setType(
CmdlineRemoteProto.Message.ControllerMessage.Type.CONSTANT_SEARCH_RESULT).setConstantSearchResult(builder.build()).build()
));
}
@@ -219,11 +219,11 @@
//}
}
}
- catch (PsiInvalidElementAccessException e) {
+ catch (PsiInvalidElementAccessException ignored) {
LOG.debug("Constant search task: PIEAE thrown while searching of usages of changed constant");
return false;
}
- catch (ProcessCanceledException e) {
+ catch (ProcessCanceledException ignored) {
LOG.debug("Constant search task: PCE thrown while searching of usages of changed constant");
return false;
}
@@ -262,7 +262,7 @@
}
return true;
}
- catch (PsiInvalidElementAccessException e) {
+ catch (PsiInvalidElementAccessException ignored) {
result.set(Boolean.FALSE);
LOG.debug("Constant search task: PIEAE thrown while searching of usages of removed constant");
return false;
@@ -285,6 +285,7 @@
private static boolean processIdentifiers(PsiSearchHelper helper, @NotNull final PsiElementProcessor<PsiIdentifier> processor, @NotNull final String identifier, @NotNull SearchScope searchScope, short searchContext) {
TextOccurenceProcessor processor1 = new TextOccurenceProcessor() {
+ @Override
public boolean execute(PsiElement element, int offsetInElement) {
return !(element instanceof PsiIdentifier) || processor.execute((PsiIdentifier)element);
}
@@ -332,7 +333,7 @@
if (containingFile == null) {
return null;
}
- return StdLanguages.JAVA.equals(containingFile.getLanguage())? psiClass : null;
+ return JavaLanguage.INSTANCE.equals(containingFile.getLanguage())? psiClass : null;
}
element = element.getParent();
}
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/MessageHandlerWrapper.java b/java/compiler/impl/src/com/intellij/compiler/server/MessageHandlerWrapper.java
index a90ff9b..68b5d5c 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/MessageHandlerWrapper.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/MessageHandlerWrapper.java
@@ -1,6 +1,6 @@
package com.intellij.compiler.server;
-import org.jboss.netty.channel.Channel;
+import io.netty.channel.Channel;
import org.jetbrains.jps.api.CmdlineRemoteProto;
import java.util.UUID;
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/BuildElementsEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/BuildElementsEditor.java
index 7476456..0b1fc42 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/BuildElementsEditor.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/BuildElementsEditor.java
@@ -146,7 +146,11 @@
private void updateOutputPathPresentation() {
if (getCompilerExtension().isCompilerOutputPathInherited()) {
- final String baseUrl = ProjectStructureConfigurable.getInstance(myProject).getProjectConfig().getCompilerOutputUrl();
+ ProjectConfigurable projectConfig = ProjectStructureConfigurable.getInstance(myProject).getProjectConfig();
+ if (projectConfig == null) {
+ return;
+ }
+ final String baseUrl = projectConfig.getCompilerOutputUrl();
moduleCompileOutputChanged(baseUrl, getModel().getModule().getName());
} else {
final VirtualFile compilerOutputPath = getCompilerExtension().getCompilerOutputPath();
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java
index fd855a7..9c6343a 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java
@@ -60,6 +60,8 @@
import java.util.ArrayList;
import java.util.List;
+import static com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurableFilter.ConfigurableId;
+
public class ProjectStructureConfigurable extends BaseConfigurable implements SearchableConfigurable, Place.Navigator {
public static final DataKey<ProjectStructureConfigurable> KEY = DataKey.create("ProjectStructureConfiguration");
@@ -220,13 +222,40 @@
addFacetsConfig();
addArtifactsConfig();
}
+
+ ProjectStructureConfigurableAdder[] adders = ProjectStructureConfigurableAdder.EP_NAME.getExtensions();
+ for (ProjectStructureConfigurableAdder adder : adders) {
+ for (Configurable configurable : adder.getExtraProjectConfigurables(myProject, myContext)) {
+ addConfigurable(configurable, true);
+ }
+ }
+
mySidePanel.addSeparator("Platform Settings");
addJdkListConfig();
addGlobalLibrariesConfig();
+
+ for (ProjectStructureConfigurableAdder adder : adders) {
+ for (Configurable configurable : adder.getExtraPlatformConfigurables(myProject, myContext)) {
+ addConfigurable(configurable, true);
+ }
+ }
}
private void addArtifactsConfig() {
- addConfigurable(myArtifactsStructureConfigurable);
+ addConfigurable(myArtifactsStructureConfigurable, ConfigurableId.ARTIFACTS);
+ }
+
+ private void addConfigurable(final Configurable configurable, final ConfigurableId configurableId) {
+ addConfigurable(configurable, isAvailable(configurableId));
+ }
+
+ private boolean isAvailable(ConfigurableId id) {
+ for (ProjectStructureConfigurableFilter filter : ProjectStructureConfigurableFilter.EP_NAME.getExtensions()) {
+ if (!filter.isAvailable(id, myProject)) {
+ return false;
+ }
+ }
+ return true;
}
public ArtifactsStructureConfigurable getArtifactsStructureConfigurable() {
@@ -235,7 +264,7 @@
private void addFacetsConfig() {
if (myFacetStructureConfigurable.isVisible()) {
- addConfigurable(myFacetStructureConfigurable);
+ addConfigurable(myFacetStructureConfigurable, ConfigurableId.FACETS);
}
}
@@ -244,25 +273,25 @@
myJdkListConfig = JdkListConfigurable.getInstance(myProject);
myJdkListConfig.init(myContext);
}
- addConfigurable(myJdkListConfig);
+ addConfigurable(myJdkListConfig, ConfigurableId.JDK_LIST);
}
private void addProjectConfig() {
myProjectConfig = new ProjectConfigurable(myProject, myContext, myModuleConfigurator, myProjectJdksModel);
- addConfigurable(myProjectConfig);
+ addConfigurable(myProjectConfig, ConfigurableId.PROJECT);
}
private void addProjectLibrariesConfig() {
- addConfigurable(myProjectLibrariesConfig);
+ addConfigurable(myProjectLibrariesConfig, ConfigurableId.PROJECT_LIBRARIES);
}
private void addGlobalLibrariesConfig() {
- addConfigurable(myGlobalLibrariesConfig);
+ addConfigurable(myGlobalLibrariesConfig, ConfigurableId.GLOBAL_LIBRARIES);
}
private void addModulesConfig() {
myModulesConfig = ModuleStructureConfigurable.getInstance(myProject);
- addConfigurable(myModulesConfig);
+ addConfigurable(myModulesConfig, ConfigurableId.MODULES);
}
@Override
@@ -579,10 +608,12 @@
return myProjectConfig;
}
- private void addConfigurable(Configurable configurable) {
+ private void addConfigurable(Configurable configurable, boolean addToSidePanel) {
myName2Config.add(configurable);
- mySidePanel.addPlace(createPlaceFor(configurable), new Presentation(configurable.getDisplayName()));
+ if (addToSidePanel) {
+ mySidePanel.addPlace(createPlaceFor(configurable), new Presentation(configurable.getDisplayName()));
+ }
}
private static Place createPlaceFor(final Configurable configurable) {
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurableAdder.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurableAdder.java
new file mode 100644
index 0000000..4a79ada
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurableAdder.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 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.roots.ui.configuration;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+public abstract class ProjectStructureConfigurableAdder {
+ public static final ExtensionPointName<ProjectStructureConfigurableAdder> EP_NAME = ExtensionPointName.create("com.intellij.projectStructureConfigurableAdder");
+
+ @NotNull
+ public List<? extends Configurable> getExtraProjectConfigurables(@NotNull Project project, @NotNull StructureConfigurableContext context) {
+ return Collections.emptyList();
+ }
+
+ @NotNull
+ public List<? extends Configurable> getExtraPlatformConfigurables(@NotNull Project project, @NotNull StructureConfigurableContext context) {
+ return Collections.emptyList();
+ }
+
+}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurableFilter.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurableFilter.java
new file mode 100644
index 0000000..9866675
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurableFilter.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 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.roots.ui.configuration;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class ProjectStructureConfigurableFilter {
+ public static final ExtensionPointName<ProjectStructureConfigurableFilter> EP_NAME = ExtensionPointName.create("com.intellij.projectStructureConfigurableFilter");
+
+ public enum ConfigurableId {
+ PROJECT, MODULES, PROJECT_LIBRARIES, FACETS, ARTIFACTS, JDK_LIST, GLOBAL_LIBRARIES
+ }
+
+ public abstract boolean isAvailable(@NotNull ConfigurableId id, @NotNull Project project);
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java
index d803b32..987f02d 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java
@@ -121,17 +121,9 @@
else {
final PsiFile containingFile = myModifierListOwner.getContainingFile();
if (!FileModificationService.getInstance().preparePsiElementForWrite(containingFile)) return;
- for (String fqn : myAnnotationsToRemove) {
- PsiAnnotation annotation = AnnotationUtil.findAnnotation(myModifierListOwner, fqn);
- if (annotation != null) {
- annotation.delete();
- }
- }
+ removePhysicalAnnotations(myModifierListOwner, myAnnotationsToRemove);
- PsiAnnotation inserted = modifierList.addAnnotation(myAnnotation);
- for (PsiNameValuePair pair : myPairs) {
- inserted.setDeclaredAttributeValue(pair.getName(), pair.getValue());
- }
+ PsiAnnotation inserted = addPhysicalAnnotation(myAnnotation, myPairs, modifierList);
JavaCodeStyleManager.getInstance(project).shortenClassReferences(inserted);
if (containingFile != file) {
UndoUtil.markPsiFileForUndo(file);
@@ -139,6 +131,23 @@
}
}
+ public static PsiAnnotation addPhysicalAnnotation(String fqn, PsiNameValuePair[] pairs, PsiModifierList modifierList) {
+ PsiAnnotation inserted = modifierList.addAnnotation(fqn);
+ for (PsiNameValuePair pair : pairs) {
+ inserted.setDeclaredAttributeValue(pair.getName(), pair.getValue());
+ }
+ return inserted;
+ }
+
+ public static void removePhysicalAnnotations(PsiModifierListOwner owner, String... fqns) {
+ for (String fqn : fqns) {
+ PsiAnnotation annotation = AnnotationUtil.findAnnotation(owner, fqn);
+ if (annotation != null) {
+ annotation.delete();
+ }
+ }
+ }
+
@NotNull
public String[] getAnnotationsToRemove() {
return myAnnotationsToRemove;
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java
index ee7a96a..144be8a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java
@@ -26,6 +26,7 @@
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
import com.intellij.psi.infos.CandidateInfo;
+import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiFormatUtilBase;
import com.intellij.ui.RowIcon;
@@ -35,6 +36,7 @@
import javax.swing.*;
import java.util.Arrays;
import java.util.List;
+import java.util.Set;
import static com.intellij.patterns.PlatformPatterns.psiElement;
@@ -55,15 +57,16 @@
andNot(psiElement().afterLeaf(psiElement().inside(PsiModifierList.class))).accepts(position)) {
final PsiClass parent = CompletionUtil.getOriginalElement((PsiClass)position.getParent().getParent().getParent());
if (parent != null) {
- addGetterSetterElements(result, parent);
- addSuperSignatureElements(parent, true, result);
- addSuperSignatureElements(parent, false, result);
+ Set<MethodSignature> addedSignatures = ContainerUtil.newHashSet();
+ addGetterSetterElements(result, parent, addedSignatures);
+ addSuperSignatureElements(parent, true, result, addedSignatures);
+ addSuperSignatureElements(parent, false, result, addedSignatures);
}
}
}
- private static void addGetterSetterElements(CompletionResultSet result, PsiClass parent) {
+ private static void addGetterSetterElements(CompletionResultSet result, PsiClass parent, Set<MethodSignature> addedSignatures) {
List<PsiMethod> prototypes = ContainerUtil.newArrayList();
for (PsiField field : parent.getFields()) {
if (!(field instanceof PsiEnumConstant)) {
@@ -72,7 +75,7 @@
}
}
for (final PsiMethod prototype : prototypes) {
- if (parent.findMethodBySignature(prototype, false) == null) {
+ if (parent.findMethodBySignature(prototype, false) == null && addedSignatures.add(prototype.getSignature(PsiSubstitutor.EMPTY))) {
Icon icon = prototype.getIcon(Iconable.ICON_FLAG_VISIBILITY);
result.addElement(createGenerateMethodElement(prototype, PsiSubstitutor.EMPTY, icon, "", new InsertHandler<LookupElement>() {
@Override
@@ -91,13 +94,14 @@
context.commitDocument();
}
- private static void addSuperSignatureElements(final PsiClass parent, boolean implemented, CompletionResultSet result) {
+ private static void addSuperSignatureElements(final PsiClass parent, boolean implemented, CompletionResultSet result, Set<MethodSignature> addedSignatures) {
for (CandidateInfo candidate : OverrideImplementExploreUtil.getMethodsToOverrideImplement(parent, implemented)) {
PsiMethod baseMethod = (PsiMethod)candidate.getElement();
assert baseMethod != null;
PsiClass baseClass = baseMethod.getContainingClass();
- if (!baseMethod.isConstructor() && baseClass != null) {
- result.addElement(createOverridingLookupElement(parent, implemented, baseMethod, baseClass, candidate.getSubstitutor()));
+ PsiSubstitutor substitutor = candidate.getSubstitutor();
+ if (!baseMethod.isConstructor() && baseClass != null && addedSignatures.add(baseMethod.getSignature(substitutor))) {
+ result.addElement(createOverridingLookupElement(parent, implemented, baseMethod, baseClass, substitutor));
}
}
}
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 6d03085..73a9e5e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java
@@ -130,16 +130,21 @@
if (myExpectedInfos != null) {
final PsiType itemType = JavaCompletionUtil.getLookupElementType(element);
- for (final ExpectedTypeInfo expectedInfo : myExpectedInfos) {
- PsiMethod calledMethod = expectedInfo.getCalledMethod();
- if (itemType != null &&
- calledMethod != null &&
- calledMethod.equals(myPositionMethod) &&
- expectedInfo.getType().isAssignableFrom(itemType)) {
- return myDelegate ? Result.delegation : Result.recursive;
+ if (itemType != null) {
+ boolean hasRecursiveInvocations = false;
+ boolean hasOtherInvocations = false;
+
+ for (final ExpectedTypeInfo expectedInfo : myExpectedInfos) {
+ PsiMethod calledMethod = expectedInfo.getCalledMethod();
+ if (!expectedInfo.getType().isAssignableFrom(itemType)) continue;
+
+ if (calledMethod != null && calledMethod.equals(myPositionMethod) || isGetterSetterAssignment(object, calledMethod)) {
+ hasRecursiveInvocations = true;
+ } else if (calledMethod != null) {
+ hasOtherInvocations = true;
+ }
}
- String propertyName = getSetterPropertyName(calledMethod);
- if (propertyName != null && isGetterSetterAssignment(object, propertyName)) {
+ if (hasRecursiveInvocations && !hasOtherInvocations) {
return myDelegate ? Result.delegation : Result.recursive;
}
}
@@ -178,7 +183,10 @@
return null;
}
- private static boolean isGetterSetterAssignment(Object lookupObject, String prop) {
+ private boolean isGetterSetterAssignment(Object lookupObject, @Nullable PsiMethod calledMethod) {
+ String prop = getSetterPropertyName(calledMethod);
+ if (prop == null) return false;
+
if (lookupObject instanceof PsiField &&
prop.equals(PropertyUtil.suggestPropertyName((PsiField)lookupObject))) {
return true;
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
index 10de8bf..8af7f8b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
@@ -806,7 +806,7 @@
DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(myProject);
PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(myDocument);
// dont optimize out imports in JSP since it can be included in other JSP
- if (file == null || !codeAnalyzer.isHighlightingAvailable(file) || !(file instanceof PsiJavaFile) || file instanceof JspFile) return false;
+ if (file == null || !codeAnalyzer.isHighlightingAvailable(file) || !(file instanceof PsiJavaFile) || file instanceof ServerPageFile) return false;
if (!codeAnalyzer.isErrorAnalyzingFinished(file)) return false;
boolean errors = containsErrorsPreventingOptimize(file);
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 2cbde60..ac90dce 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
@@ -252,14 +252,14 @@
referenceClass != null ? HighlightUtil.formatClass(referenceClass) : type.getPresentableText(),
JavaHighlightUtil.formatType(bound));
- final HighlightInfo highlightInfo =
+ final HighlightInfo info =
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement2Highlight).descriptionAndTooltip(description).create();
- if (bound instanceof PsiClassType && referenceClass != null) {
+ if (bound instanceof PsiClassType && referenceClass != null && info != null) {
QuickFixAction
- .registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createExtendsListFix(referenceClass, (PsiClassType)bound, true),
+ .registerQuickFixAction(info, QUICK_FIX_FACTORY.createExtendsListFix(referenceClass, (PsiClassType)bound, true),
null);
}
- return highlightInfo;
+ return info;
}
}
return null;
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 449df8e..e2babf5 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
@@ -47,7 +47,6 @@
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import com.intellij.refactoring.util.RefactoringChangeUtil;
@@ -893,7 +892,7 @@
PsiClass outerClass = aClass.getContainingClass();
if (outerClass == null) return null;
- if (outerClass instanceof JspClass || hasEnclosingInstanceInScope(outerClass, placeToSearchEnclosingFrom, true, false)) return null;
+ if (outerClass instanceof PsiSyntheticClass || hasEnclosingInstanceInScope(outerClass, placeToSearchEnclosingFrom, true, false)) return null;
return reportIllegalEnclosingUsage(placeToSearchEnclosingFrom, aClass, outerClass, element);
}
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 0aa08d0b..636b033 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
@@ -1198,7 +1198,8 @@
return null;
}
- public static TextRange getFixRange(PsiElement element) {
+ @NotNull
+ public static TextRange getFixRange(@NotNull PsiElement element) {
TextRange range = element.getTextRange();
int start = range.getStartOffset();
int end = range.getEndOffset();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java
index a8c041e..b9ea90c 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java
@@ -19,21 +19,19 @@
*/
package com.intellij.codeInsight.daemon.impl.analysis;
-import com.intellij.application.options.colors.ColorAndFontOptions;
-import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
-import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
+import com.intellij.application.options.colors.ScopeAttributesUtil;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.colors.TextAttributesScheme;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
+import com.intellij.packageDependencies.DependencyValidationManager;
+import com.intellij.packageDependencies.DependencyValidationManagerImpl;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.impl.source.tree.TreeUtil;
import com.intellij.psi.search.scope.packageSet.NamedScope;
@@ -233,14 +231,14 @@
PsiFile file = element.getContainingFile();
if (file == null) return null;
TextAttributes result = null;
- final DaemonCodeAnalyzerImpl daemonCodeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(file.getProject());
- List<Pair<NamedScope,NamedScopesHolder>> scopes = daemonCodeAnalyzer.getScopeBasedHighlightingCachedScopes();
+ DependencyValidationManagerImpl validationManager = (DependencyValidationManagerImpl)DependencyValidationManager.getInstance(file.getProject());
+ List<Pair<NamedScope,NamedScopesHolder>> scopes = validationManager.getScopeBasedHighlightingCachedScopes();
for (Pair<NamedScope, NamedScopesHolder> scope : scopes) {
NamedScope namedScope = scope.getFirst();
NamedScopesHolder scopesHolder = scope.getSecond();
PackageSet packageSet = namedScope.getValue();
if (packageSet != null && packageSet.contains(file, scopesHolder)) {
- TextAttributesKey scopeKey = ColorAndFontOptions.getScopeTextAttributeKey(namedScope.getName());
+ TextAttributesKey scopeKey = ScopeAttributesUtil.getScopeTextAttributeKey(namedScope.getName());
TextAttributes attributes = colorsScheme.getAttributes(scopeKey);
if (attributes == null || attributes.isEmpty()) {
continue;
@@ -252,7 +250,7 @@
}
public static TextRange getMethodDeclarationTextRange(@NotNull PsiMethod method) {
- if (method instanceof JspHolderMethod) return TextRange.EMPTY_RANGE;
+ if (method instanceof SyntheticElement) return TextRange.EMPTY_RANGE;
int start = stripAnnotationsFromModifierList(method.getModifierList());
final TextRange throwsRange = method.getThrowsList().getTextRange();
LOG.assertTrue(throwsRange != null, method);
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 5c59702..5657a40 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
@@ -2603,11 +2603,13 @@
return info;
}
- public static void registerChangeVariableTypeFixes(PsiVariable parameter, PsiType itemType, HighlightInfo highlightInfo) {
+ public static void registerChangeVariableTypeFixes(@NotNull PsiVariable parameter, PsiType itemType, HighlightInfo highlightInfo) {
if (itemType instanceof PsiMethodReferenceType) return;
- for (ChangeVariableTypeQuickFixProvider fixProvider : Extensions.getExtensions(ChangeVariableTypeQuickFixProvider.EP_NAME)) {
- for (IntentionAction action : fixProvider.getFixes(parameter, itemType)) {
- QuickFixAction.registerQuickFixAction(highlightInfo, action);
+ if (itemType != null) {
+ for (ChangeVariableTypeQuickFixProvider fixProvider : Extensions.getExtensions(ChangeVariableTypeQuickFixProvider.EP_NAME)) {
+ for (IntentionAction action : fixProvider.getFixes(parameter, itemType)) {
+ QuickFixAction.registerQuickFixAction(highlightInfo, action);
+ }
}
}
ChangeParameterClassFix.registerQuickFixAction(parameter.getType(), itemType, highlightInfo);
@@ -2656,10 +2658,12 @@
LAMBDA_EXPRESSIONS(LanguageLevel.JDK_1_8, "feature.lambda.expressions"),
TYPE_ANNOTATIONS(LanguageLevel.JDK_1_8, "feature.type.annotations");
+ @NotNull
private final LanguageLevel level;
+ @NotNull
private final String key;
- Feature(final LanguageLevel level, @PropertyKey(resourceBundle = JavaErrorMessages.BUNDLE) final String key) {
+ Feature(@NotNull LanguageLevel level, @NotNull @PropertyKey(resourceBundle = JavaErrorMessages.BUNDLE) final String key) {
this.level = level;
this.key = key;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/IncreaseLanguageLevelFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/IncreaseLanguageLevelFix.java
index a4db183..a3f235e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/IncreaseLanguageLevelFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/IncreaseLanguageLevelFix.java
@@ -21,11 +21,10 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
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.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.projectRoots.JdkVersionUtil;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.vfs.VirtualFile;
@@ -43,7 +42,7 @@
private final LanguageLevel myLevel;
- public IncreaseLanguageLevelFix(LanguageLevel targetLevel) {
+ public IncreaseLanguageLevelFix(@NotNull LanguageLevel targetLevel) {
myLevel = targetLevel;
}
@@ -59,10 +58,10 @@
return CodeInsightBundle.message("set.language.level");
}
- private static boolean isJdkSupportsLevel(@Nullable final Sdk jdk, final LanguageLevel level) {
+ private static boolean isJdkSupportsLevel(@Nullable final Sdk jdk, @NotNull LanguageLevel level) {
if (jdk == null) return true;
- final JavaSdk sdk = JavaSdk.getInstance();
- final JavaSdkVersion version = sdk.getVersion(jdk);
+ String versionString = jdk.getVersionString();
+ JavaSdkVersion version = versionString == null ? null : JdkVersionUtil.getVersion(versionString);
return version != null && version.getMaxLanguageLevel().isAtLeast(level);
}
@@ -74,7 +73,7 @@
return isLanguageLevelAcceptable(project, module, myLevel);
}
- public static boolean isLanguageLevelAcceptable(final Project project, Module module, final LanguageLevel level) {
+ private static boolean isLanguageLevelAcceptable(@NotNull Project project, Module module, @NotNull LanguageLevel level) {
return isJdkSupportsLevel(getRelevantJdk(project, module), level);
}
@@ -100,7 +99,7 @@
}
@Nullable
- private static Sdk getRelevantJdk(final Project project, @Nullable Module module) {
+ private static Sdk getRelevantJdk(@NotNull Project project, @Nullable Module module) {
Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectSdk();
Sdk moduleJdk = module == null ? null : ModuleRootManager.getInstance(module).getSdk();
return moduleJdk == null ? projectJdk : moduleJdk;
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorParameterFromFieldFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorParameterFromFieldFix.java
index ac607483..2fc03f8 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorParameterFromFieldFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorParameterFromFieldFix.java
@@ -38,7 +38,6 @@
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
import com.intellij.psi.codeStyle.VariableKind;
-import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
@@ -91,7 +90,7 @@
&& field.getManager().isInProject(field)
&& !field.hasModifierProperty(PsiModifier.STATIC)
&& containingClass != null
- && !(containingClass instanceof JspClass)
+ && !(containingClass instanceof PsiSyntheticClass)
&& containingClass.getName() != null;
}
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 b30a19f..06704aa 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
@@ -28,12 +28,12 @@
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
-import java.util.HashMap;
+import java.util.EnumMap;
import java.util.Map;
public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider<PsiJavaCodeReferenceElement> {
@Override
- public void registerFixes(PsiJavaCodeReferenceElement ref, QuickFixActionRegistrar registrar) {
+ public void registerFixes(@NotNull PsiJavaCodeReferenceElement ref, @NotNull QuickFixActionRegistrar registrar) {
registrar.register(new ImportClassFix(ref));
registrar.register(SetupJDKFix.getInstance());
@@ -80,7 +80,7 @@
@NotNull PsiReferenceExpression refExpr) {
final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(refExpr.getProject());
- final Map<VariableKind, IntentionAction> map = new HashMap<VariableKind, IntentionAction>();
+ final Map<VariableKind, IntentionAction> map = new EnumMap<VariableKind, IntentionAction>(VariableKind.class);
map.put(VariableKind.FIELD, new CreateFieldFromUsageFix(refExpr));
map.put(VariableKind.STATIC_FINAL_FIELD, new CreateConstantFieldFromUsageFix(refExpr));
if (!refExpr.isQualified()) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeQuickFixProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeQuickFixProvider.java
index 5b500b8..46b172a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeQuickFixProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeQuickFixProvider.java
@@ -24,10 +24,12 @@
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.psi.PsiVariable;
import com.intellij.psi.PsiType;
+import org.jetbrains.annotations.NotNull;
public class VariableTypeQuickFixProvider implements ChangeVariableTypeQuickFixProvider{
+ @NotNull
@Override
- public IntentionAction[] getFixes(PsiVariable variable, PsiType toReturn) {
+ public IntentionAction[] getFixes(@NotNull PsiVariable variable, @NotNull PsiType toReturn) {
return new IntentionAction[]{new VariableTypeFix(variable, toReturn)};
}
}
\ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java
index 041149c..0f9bc4f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java
@@ -61,7 +61,9 @@
}
final PsiExpression[] params = args.getExpressions();
- if (params.length > 0 && startLine(editor, args) != startLine(editor, params[0])) {
+ if (params.length > 0 &&
+ startLine(editor, args) != startLine(editor, params[0]) &&
+ editor.getCaretModel().getOffset() < params[0].getTextRange().getStartOffset()) {
endOffset = args.getTextRange().getStartOffset() + 1;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java
index 1b08887..c6cdb98 100644
--- a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java
@@ -22,7 +22,6 @@
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
-import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
import org.jetbrains.annotations.Nullable;
public class JavaFoldingBuilder extends JavaFoldingBuilderBase {
@@ -47,8 +46,9 @@
@Nullable
@Override
public TextRange getRangeToFold(PsiElement element) {
- if (element instanceof JspHolderMethod)
+ if (element instanceof SyntheticElement) {
return null;
+ }
return super.getRangeToFold(element); //To change body of overridden methods use File | Settings | File Templates.
}
}
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 01d7187..f33c6e4 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
@@ -20,6 +20,7 @@
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.MethodImplementor;
import com.intellij.codeInsight.intention.AddAnnotationFix;
+import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.featureStatistics.ProductivityFeatureNames;
import com.intellij.ide.fileTemplates.FileTemplate;
@@ -53,7 +54,6 @@
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.search.GlobalSearchScope;
@@ -246,7 +246,7 @@
public static void annotateOnOverrideImplement(PsiMethod method, PsiClass targetClass, PsiMethod overridden, boolean insertOverride) {
if (insertOverride && canInsertOverride(overridden, targetClass)) {
- annotate(method, Override.class.getName());
+ AddAnnotationPsiFix.addPhysicalAnnotation(Override.class.getName(), PsiNameValuePair.EMPTY_ARRAY, method.getModifierList());
}
final Module module = ModuleUtilCore.findModuleForPsiElement(targetClass);
final GlobalSearchScope moduleScope = module != null ? GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) : null;
@@ -256,7 +256,8 @@
for (String annotation : each.getAnnotations(project)) {
if (moduleScope != null && facade.findClass(annotation, moduleScope) == null) continue;
if (AnnotationUtil.isAnnotated(overridden, annotation, false, false)) {
- annotate(method, annotation, each.annotationsToRemove(project, annotation));
+ AddAnnotationPsiFix.removePhysicalAnnotations(method, each.annotationsToRemove(project, annotation));
+ AddAnnotationPsiFix.addPhysicalAnnotation(annotation, PsiNameValuePair.EMPTY_ARRAY, method.getModifierList());
}
}
}
@@ -577,7 +578,7 @@
if (name != null) {
MethodSignature signature = MethodSignatureUtil.createMethodSignature(name, nextBaseMethod.getParameterList(), nextBaseMethod.getTypeParameterList(), substitutor, nextBaseMethod.isConstructor());
PsiMethod nextMethod = MethodSignatureUtil.findMethodBySignature(aClass, signature, false);
- if (nextMethod != null){
+ if (nextMethod != null && nextMethod.isPhysical()){
return nextMethod;
}
}
@@ -624,7 +625,7 @@
while (element instanceof PsiTypeParameter);
final PsiClass aClass = (PsiClass)element;
- if (aClass instanceof JspClass) return null;
+ if (aClass instanceof PsiSyntheticClass) return null;
return aClass == null || !allowInterface && aClass.isInterface() ? null : aClass;
}
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 556c762..4756a5b 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
@@ -26,7 +26,6 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.util.RefactoringChangeUtil;
@@ -52,7 +51,7 @@
if (!field.hasInitializer()) return false;
PsiClass psiClass = field.getContainingClass();
- return psiClass != null && !psiClass.isInterface() && !(psiClass instanceof PsiAnonymousClass) && !(psiClass instanceof JspClass);
+ return psiClass != null && !psiClass.isInterface() && !(psiClass instanceof PsiAnonymousClass) && !(psiClass instanceof PsiSyntheticClass);
}
private boolean hasUnsuitableModifiers(@NotNull PsiField field) {
diff --git a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspection.java
index c740b78..f06bf08 100644
--- a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocLocalInspection.java
@@ -22,8 +22,6 @@
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.javadoc.PsiDocParamRef;
-import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
-import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
import com.intellij.psi.javadoc.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PropertyUtil;
@@ -421,7 +419,7 @@
@Nullable
public ProblemDescriptor[] checkClass(@NotNull PsiClass psiClass, @NotNull InspectionManager manager, boolean isOnTheFly) {
if (psiClass instanceof PsiAnonymousClass) return null;
- if (psiClass instanceof JspClass) return null;
+ if (psiClass instanceof PsiSyntheticClass) return null;
if (psiClass instanceof PsiTypeParameter) return null;
if (IGNORE_DEPRECATED && psiClass.isDeprecated()) {
return null;
@@ -553,7 +551,7 @@
@Override
@Nullable
public ProblemDescriptor[] checkMethod(@NotNull PsiMethod psiMethod, @NotNull InspectionManager manager, boolean isOnTheFly) {
- if (psiMethod instanceof JspHolderMethod) return null;
+ if (psiMethod instanceof SyntheticElement) return null;
if (IGNORE_DEPRECATED && (psiMethod.isDeprecated() || psiMethod.getContainingClass().isDeprecated())) {
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 b740fcf..609a4fc 100644
--- a/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java
@@ -473,14 +473,16 @@
}
}
- public static LocalQuickFix[] getChangeVariableTypeFixes(PsiVariable parameter, PsiType itemType) {
+ public static LocalQuickFix[] getChangeVariableTypeFixes(@NotNull PsiVariable parameter, PsiType itemType) {
if (itemType instanceof PsiMethodReferenceType) return LocalQuickFix.EMPTY_ARRAY;
final List<LocalQuickFix> result = new ArrayList<LocalQuickFix>();
LOG.assertTrue(parameter.isValid());
- for (ChangeVariableTypeQuickFixProvider fixProvider : Extensions.getExtensions(ChangeVariableTypeQuickFixProvider.EP_NAME)) {
- for (IntentionAction action : fixProvider.getFixes(parameter, itemType)) {
- if (action instanceof LocalQuickFix) {
- result.add((LocalQuickFix)action);
+ if (itemType != null) {
+ for (ChangeVariableTypeQuickFixProvider fixProvider : Extensions.getExtensions(ChangeVariableTypeQuickFixProvider.EP_NAME)) {
+ for (IntentionAction action : fixProvider.getFixes(parameter, itemType)) {
+ if (action instanceof LocalQuickFix) {
+ result.add((LocalQuickFix)action);
+ }
}
}
}
diff --git a/java/java-impl/src/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java b/java/java-impl/src/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java
index c465975..e01c21c 100644
--- a/java/java-impl/src/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java
+++ b/java/java-impl/src/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java
@@ -33,7 +33,6 @@
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.Navigatable;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
import com.intellij.psi.presentation.java.ClassPresentationUtil;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiTreeUtil;
@@ -125,7 +124,7 @@
mainTextAttributes = new TextAttributes(myColor, null, null, null, Font.PLAIN);
}
if (enclosingElement instanceof PsiMethod) {
- if (enclosingElement instanceof JspHolderMethod) {
+ if (enclosingElement instanceof SyntheticElement) {
PsiFile file = enclosingElement.getContainingFile();
myHighlightedText.getEnding().addText(file != null ? file.getName() : IdeBundle.message("node.call.hierarchy.unknown.jsp"), mainTextAttributes);
}
diff --git a/java/java-impl/src/com/intellij/ide/hierarchy/method/OverrideImplementMethodAction.java b/java/java-impl/src/com/intellij/ide/hierarchy/method/OverrideImplementMethodAction.java
index 1bc9f6f..2b09e70 100644
--- a/java/java-impl/src/com/intellij/ide/hierarchy/method/OverrideImplementMethodAction.java
+++ b/java/java-impl/src/com/intellij/ide/hierarchy/method/OverrideImplementMethodAction.java
@@ -28,11 +28,7 @@
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiSubstitutor;
-import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
+import com.intellij.psi.*;
import com.intellij.psi.util.MethodSignature;
import com.intellij.util.IncorrectOperationException;
@@ -151,7 +147,7 @@
private static boolean canImplementOverride(final MethodHierarchyNodeDescriptor descriptor, final MethodHierarchyBrowser methodHierarchyBrowser, final boolean toImplement) {
final PsiClass psiClass = descriptor.getPsiClass();
- if (psiClass == null || psiClass instanceof JspClass) return false;
+ if (psiClass == null || psiClass instanceof PsiSyntheticClass) return false;
final PsiMethod baseMethod = methodHierarchyBrowser.getBaseMethod();
if (baseMethod == null) return false;
final MethodSignature signature = baseMethod.getSignature(PsiSubstitutor.EMPTY);
diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java b/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java
index 570e42e..bcca6cd 100644
--- a/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java
+++ b/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java
@@ -29,7 +29,6 @@
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.jsp.JspFile;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -47,7 +46,7 @@
ArrayList<AbstractTreeNode> result = new ArrayList<AbstractTreeNode>();
for (final AbstractTreeNode child : children) {
Object o = child.getValue();
- if (o instanceof PsiClassOwner && !(o instanceof JspFile)) {
+ if (o instanceof PsiClassOwner && !(o instanceof ServerPageFile)) {
final ViewSettings settings1 = ((ProjectViewNode)parent).getSettings();
final PsiClassOwner classOwner = (PsiClassOwner)o;
final VirtualFile file = classOwner.getVirtualFile();
@@ -181,6 +180,6 @@
}
return result;
}
-
+
}
}
diff --git a/java/java-impl/src/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java b/java/java-impl/src/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java
index 06a5920..2f186db 100644
--- a/java/java-impl/src/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java
+++ b/java/java-impl/src/com/intellij/ide/structureView/impl/java/PsiMethodTreeElement.java
@@ -24,7 +24,6 @@
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
import com.intellij.psi.search.searches.SuperMethodsSearch;
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
import com.intellij.psi.util.PsiFormatUtil;
@@ -45,11 +44,12 @@
super(isInherited, method);
}
+ @Override
@NotNull
public Collection<StructureViewTreeElement> getChildrenBase() {
final ArrayList<StructureViewTreeElement> result = new ArrayList<StructureViewTreeElement>();
final PsiMethod element = getElement();
- if (element == null || element instanceof JspHolderMethod) return result;
+ if (element == null || element instanceof SyntheticElement) return result;
final TextRange range = element.getTextRange();
if (range == null) return result;
@@ -72,6 +72,7 @@
return result;
}
+ @Override
public String getPresentableText() {
String method = PsiFormatUtil.formatMethod(getElement(),
PsiSubstitutor.EMPTY,
@@ -126,6 +127,7 @@
return getElement();
}
+ @Override
public String getAlphaSortKey() {
final PsiMethod method = getElement();
if (method != null) {
diff --git a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java
index d123dff..0738da4 100644
--- a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java
+++ b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java
@@ -15,6 +15,7 @@
*/
package com.intellij.ide.util.gotoByName;
+import com.intellij.navigation.EfficientChooseByNameContributor;
import com.intellij.navigation.GotoClassContributor;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.project.Project;
@@ -22,14 +23,27 @@
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.CommonProcessors;
+import com.intellij.util.Processor;
+import com.intellij.util.indexing.FileBasedIndex;
+import com.intellij.util.indexing.IdFilter;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
-public class DefaultClassNavigationContributor implements GotoClassContributor {
+public class DefaultClassNavigationContributor implements EfficientChooseByNameContributor, GotoClassContributor {
@Override
@NotNull
public String[] getNames(Project project, boolean includeNonProjectItems) {
+ if (FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping) {
+ GlobalSearchScope scope = includeNonProjectItems ? GlobalSearchScope.allScope(project) : GlobalSearchScope.projectScope(project);
+ CommonProcessors.CollectProcessor<String> processor = new CommonProcessors.CollectProcessor<String>();
+ processNames(processor, scope, DefaultFileNavigationContributor.getFilter(project, includeNonProjectItems));
+
+ return ArrayUtil.toStringArray(processor.getResults());
+ }
+
return PsiShortNamesCache.getInstance(project).getAllClassNames();
}
@@ -54,18 +68,26 @@
@Override
public String getQualifiedName(final NavigationItem item) {
if (item instanceof PsiClass) {
- final PsiClass psiClass = (PsiClass)item;
- final String qName = psiClass.getQualifiedName();
- if (qName != null) return qName;
-
- final String containerText = SymbolPresentationUtil.getSymbolContainerText(psiClass);
- return containerText + "." + psiClass.getName();
+ return getQualifiedNameForClass((PsiClass)item);
}
return null;
}
+ public static String getQualifiedNameForClass(PsiClass psiClass) {
+ final String qName = psiClass.getQualifiedName();
+ if (qName != null) return qName;
+
+ final String containerText = SymbolPresentationUtil.getSymbolContainerText(psiClass);
+ return containerText + "." + psiClass.getName();
+ }
+
@Override
public String getQualifiedNameSeparator() {
return ".";
}
+
+ @Override
+ public void processNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+ PsiShortNamesCache.getInstance(scope.getProject()).processAllClassNames(processor, scope, filter);
+ }
}
\ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/jarFinder/FindJarQuickFixProvider.java b/java/java-impl/src/com/intellij/jarFinder/FindJarQuickFixProvider.java
index 9cf66d3..fbf7ae9 100644
--- a/java/java-impl/src/com/intellij/jarFinder/FindJarQuickFixProvider.java
+++ b/java/java-impl/src/com/intellij/jarFinder/FindJarQuickFixProvider.java
@@ -10,7 +10,7 @@
*/
public class FindJarQuickFixProvider extends UnresolvedReferenceQuickFixProvider<PsiJavaCodeReferenceElement> {
@Override
- public void registerFixes(PsiJavaCodeReferenceElement ref, QuickFixActionRegistrar registrar) {
+ public void registerFixes(@NotNull PsiJavaCodeReferenceElement ref, @NotNull QuickFixActionRegistrar registrar) {
registrar.register(new JavaFindJarFix(ref));
}
diff --git a/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java b/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java
index 6b1a322..52c68a0 100644
--- a/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java
+++ b/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java
@@ -43,7 +43,6 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.jsp.JspFile;
import com.intellij.util.PathsList;
import com.intellij.util.containers.HashSet;
import org.jdom.Element;
@@ -348,7 +347,7 @@
if (file instanceof PsiJavaFile) {
final PsiJavaFile javaFile = (PsiJavaFile)file;
final String packageName = javaFile.getPackageName();
- if (containsPackagePrefix(module, packageName) || (packageName.length() == 0 && !(javaFile instanceof JspFile)) || !myUsePackageNotation) {
+ if (containsPackagePrefix(module, packageName) || (packageName.length() == 0 && !(javaFile instanceof ServerPageFile)) || !myUsePackageNotation) {
mySourceFiles.add(FileUtil.toSystemIndependentName(fileOrDir.getPath()));
}
else {
diff --git a/java/java-impl/src/com/intellij/lang/java/JavaRefactoringSupportProvider.java b/java/java-impl/src/com/intellij/lang/java/JavaRefactoringSupportProvider.java
index 5b0013c..67b4397 100644
--- a/java/java-impl/src/com/intellij/lang/java/JavaRefactoringSupportProvider.java
+++ b/java/java-impl/src/com/intellij/lang/java/JavaRefactoringSupportProvider.java
@@ -35,6 +35,7 @@
import com.intellij.refactoring.introduceVariable.IntroduceVariableHandler;
import com.intellij.refactoring.memberPullUp.JavaPullUpHandler;
import com.intellij.refactoring.memberPushDown.JavaPushDownHandler;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -42,7 +43,7 @@
*/
public class JavaRefactoringSupportProvider extends RefactoringSupportProvider {
@Override
- public boolean isSafeDeleteAvailable(PsiElement element) {
+ public boolean isSafeDeleteAvailable(@NotNull PsiElement element) {
return element instanceof PsiClass || element instanceof PsiMethod || element instanceof PsiField ||
(element instanceof PsiParameter && ((PsiParameter)element).getDeclarationScope() instanceof PsiMethod) ||
element instanceof PsiPackage || element instanceof PsiLocalVariable;
@@ -59,12 +60,12 @@
}
@Override
- public boolean isInplaceRenameAvailable(final PsiElement element, final PsiElement context) {
+ public boolean isInplaceRenameAvailable(@NotNull final PsiElement element, final PsiElement context) {
return mayRenameInplace(element, context);
}
@Override
- public boolean isMemberInplaceRenameAvailable(PsiElement elementToRename, PsiElement context) {
+ public boolean isMemberInplaceRenameAvailable(@NotNull PsiElement elementToRename, @Nullable PsiElement context) {
return elementToRename instanceof PsiMember;
}
@@ -115,7 +116,7 @@
}
@Override
- public boolean isInplaceIntroduceAvailable(PsiElement element, PsiElement context) {
+ public boolean isInplaceIntroduceAvailable(@NotNull PsiElement element, PsiElement context) {
if (!(element instanceof PsiExpression)) return false;
if (context == null || context.getContainingFile() != element.getContainingFile()) return false;
return true;
diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/CodeBlockBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/CodeBlockBlock.java
index 3b03958..bcec4ef 100644
--- a/java/java-impl/src/com/intellij/psi/formatter/java/CodeBlockBlock.java
+++ b/java/java-impl/src/com/intellij/psi/formatter/java/CodeBlockBlock.java
@@ -20,11 +20,11 @@
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaTokenType;
+import com.intellij.psi.PsiSyntheticClass;
import com.intellij.psi.TokenType;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.formatter.FormatterUtil;
import com.intellij.psi.formatter.common.AbstractBlock;
-import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
import com.intellij.psi.impl.source.tree.JavaDocElementType;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.StdTokenSets;
@@ -59,7 +59,7 @@
/**
* There is a possible case that 'implements' section is incomplete (e.g. ends with comma). We may want to align lbrace
* to the comma then.
- *
+ *
* @param alignment block alignment
* @param baseNode base AST node
* @return alignment strategy to use for the given node
@@ -86,7 +86,7 @@
}
return AlignmentStrategy.wrap(alignment);
}
-
+
private boolean isSwitchCodeBlock() {
return myNode.getTreeParent().getElementType() == JavaElementType.SWITCH_STATEMENT;
}
@@ -108,7 +108,7 @@
int state = BEFORE_FIRST;
- if (myNode.getPsi() instanceof JspClass) {
+ if (myNode.getPsi() instanceof PsiSyntheticClass) {
state = INSIDE_BODY;
}
@@ -157,7 +157,7 @@
}
return StringUtil.countNewLines(whiteSpaceCandidate.getChars()) > 0 ? myAlignment : defaultAlignment;
}
-
+
@Nullable
private ASTNode processCaseAndStatementAfter(final ArrayList<Block> result,
ASTNode child,
diff --git a/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java b/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java
index d93136c..3794863 100644
--- a/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java
+++ b/java/java-impl/src/com/intellij/psi/impl/search/JavaIndexPatternBuilder.java
@@ -17,10 +17,7 @@
import com.intellij.lang.java.JavaParserDefinition;
import com.intellij.lexer.Lexer;
-import com.intellij.psi.JavaDocTokenType;
-import com.intellij.psi.JavaTokenType;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiJavaFile;
+import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.StdTokenSets;
import com.intellij.psi.jsp.JspFile;
import com.intellij.psi.tree.IElementType;
@@ -48,7 +45,7 @@
@Override
@Nullable
public TokenSet getCommentTokenSet(final PsiFile file) {
- if (file instanceof PsiJavaFile && !(file instanceof JspFile)) {
+ if (file instanceof PsiJavaFile && !(file instanceof ServerPageFile)) {
return TokenSet.orSet(StdTokenSets.COMMENT_BIT_SET, XML_COMMENT_BIT_SET, JavaDocTokenType.ALL_JAVADOC_TOKENS, XML_DATA_CHARS);
}
return null;
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java
index 5e4f279..58457da 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java
@@ -41,7 +41,6 @@
import com.intellij.psi.impl.source.resolve.reference.impl.GenericReference;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.infos.ClassCandidateInfo;
-import com.intellij.psi.jsp.JspFile;
import com.intellij.psi.scope.JavaScopeProcessorEvent;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.search.GlobalSearchScope;
@@ -413,7 +412,7 @@
PsiFile containingFile = psiElement.getContainingFile();
if (containingFile instanceof PsiJavaFile) {
- if (containingFile instanceof JspFile) {
+ if (containingFile instanceof ServerPageFile) {
containingFile = containingFile.getViewProvider().getPsi(JavaLanguage.INSTANCE);
if (containingFile == null) return JavaResolveResult.EMPTY;
}
diff --git a/java/java-impl/src/com/intellij/psi/util/proximity/ReferenceListWeigher.java b/java/java-impl/src/com/intellij/psi/util/proximity/ReferenceListWeigher.java
index 217585f..b7d29f1 100644
--- a/java/java-impl/src/com/intellij/psi/util/proximity/ReferenceListWeigher.java
+++ b/java/java-impl/src/com/intellij/psi/util/proximity/ReferenceListWeigher.java
@@ -18,6 +18,7 @@
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.patterns.PlatformPatterns;
+import com.intellij.patterns.PsiElementPattern;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.ProximityLocation;
@@ -29,6 +30,9 @@
*/
public class ReferenceListWeigher extends ProximityWeigher {
+ private static final PsiElementPattern.Capture<PsiElement> INSIDE_REFERENCE_LIST =
+ PlatformPatterns.psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiReferenceList.class);
+
protected enum Preference {
Interfaces, Classes, Exceptions
}
@@ -36,7 +40,7 @@
@Nullable
protected Preference getPreferredCondition(@NotNull ProximityLocation location) {
PsiElement position = location.getPosition();
- if (PlatformPatterns.psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiReferenceList.class).accepts(position)) {
+ if (INSIDE_REFERENCE_LIST.accepts(position)) {
assert position != null;
PsiReferenceList list = (PsiReferenceList)position.getParent().getParent();
PsiReferenceList.Role role = list.getRole();
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
index 7279f90..eee40ea 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
@@ -1239,8 +1239,16 @@
public boolean isDeclaredInside(PsiVariable variable) {
if (variable instanceof ImplicitVariable) return false;
- int startOffset = myElements[0].getTextRange().getStartOffset();
- int endOffset = myElements[myElements.length - 1].getTextRange().getEndOffset();
+ int startOffset;
+ int endOffset;
+ if (myExpression != null) {
+ final TextRange range = myExpression.getTextRange();
+ startOffset = range.getStartOffset();
+ endOffset = range.getEndOffset();
+ } else {
+ startOffset = myElements[0].getTextRange().getStartOffset();
+ endOffset = myElements[myElements.length - 1].getTextRange().getEndOffset();
+ }
PsiIdentifier nameIdentifier = variable.getNameIdentifier();
if (nameIdentifier == null) return false;
final TextRange range = nameIdentifier.getTextRange();
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
index 9d64136..271e832 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
@@ -211,7 +211,7 @@
}*/
PsiExpression expression = PsiTreeUtil.getParentOfType(elementAtCaret, PsiExpression.class);
while (expression != null) {
- if (!expressions.contains(expression) && !(expression instanceof PsiParenthesizedExpression) && !(expression instanceof PsiSuperExpression) &&
+ if (!expressions.contains(expression) && !(expression instanceof PsiParenthesizedExpression) && !(expression instanceof PsiSuperExpression) &&
(acceptVoid || expression.getType() != PsiType.VOID)) {
if (expression instanceof PsiMethodReferenceExpression) {
expressions.add(expression);
@@ -570,7 +570,7 @@
final PsiFile file = anchorStatement.getContainingFile();
LOG.assertTrue(file != null, "expr.getContainingFile() == null");
- final PsiElement nameSuggestionContext = editor != null ? file.findElementAt(editor.getCaretModel().getOffset()) : null;
+ final PsiElement nameSuggestionContext = editor == null ? null : file.findElementAt(editor.getCaretModel().getOffset());
final RefactoringSupportProvider supportProvider = LanguageRefactoringSupport.INSTANCE.forLanguage(expr.getLanguage());
final boolean isInplaceAvailableOnDataContext =
supportProvider != null &&
diff --git a/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java b/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java
index 032d5ff..c7589f9 100644
--- a/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java
+++ b/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java
@@ -72,7 +72,7 @@
}
}
- public boolean checkTargetClassConflicts(final PsiClass targetClass, final boolean checkStatic, final PsiElement context) {
+ public void checkTargetClassConflicts(final PsiClass targetClass, final boolean checkStatic, final PsiElement context) {
if (targetClass != null) {
for (final PsiMember movedMember : myMovedMembers) {
checkMemberPlacementInTargetClassConflict(targetClass, movedMember);
@@ -98,43 +98,39 @@
});
}
}
- Runnable searchConflictsRunnable = new Runnable() {
- public void run() {
- Members:
- for (PsiMember member : myMovedMembers) {
- for (PsiReference ref : ReferencesSearch.search(member, member.getResolveScope(), false)) {
- final PsiElement element = ref.getElement();
- if (element instanceof PsiReferenceExpression) {
- final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)element;
- final PsiExpression qualifier = referenceExpression.getQualifierExpression();
- if (qualifier != null) {
- final PsiType qualifierType = qualifier.getType();
- PsiClass aClass = null;
- if (qualifierType instanceof PsiClassType) {
- aClass = ((PsiClassType)qualifierType).resolve();
- }
- else {
- if (!checkStatic) continue;
- if (qualifier instanceof PsiReferenceExpression) {
- final PsiElement resolved = ((PsiReferenceExpression)qualifier).resolve();
- if (resolved instanceof PsiClass) {
- aClass = (PsiClass)resolved;
- }
- }
- }
-
- if (!InheritanceUtil.isInheritorOrSelf(aClass, targetClass, true)) {
- myConflicts.putValue(referenceExpression, RefactoringBundle.message("pushed.members.will.not.be.visible.from.certain.call.sites"));
- break Members;
+ Members:
+ for (PsiMember member : myMovedMembers) {
+ for (PsiReference ref : ReferencesSearch.search(member, member.getResolveScope(), false)) {
+ final PsiElement element = ref.getElement();
+ if (element instanceof PsiReferenceExpression) {
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)element;
+ final PsiExpression qualifier = referenceExpression.getQualifierExpression();
+ if (qualifier != null) {
+ final PsiType qualifierType = qualifier.getType();
+ PsiClass aClass = null;
+ if (qualifierType instanceof PsiClassType) {
+ aClass = ((PsiClassType)qualifierType).resolve();
+ }
+ else {
+ if (!checkStatic) continue;
+ if (qualifier instanceof PsiReferenceExpression) {
+ final PsiElement resolved = ((PsiReferenceExpression)qualifier).resolve();
+ if (resolved instanceof PsiClass) {
+ aClass = (PsiClass)resolved;
}
}
}
+
+ if (!InheritanceUtil.isInheritorOrSelf(aClass, targetClass, true)) {
+ myConflicts.putValue(referenceExpression, RefactoringBundle.message("pushed.members.will.not.be.visible.from.certain.call.sites"));
+ break Members;
+ }
}
}
- RefactoringConflictsUtil.analyzeAccessibilityConflicts(myMovedMembers, targetClass, myConflicts, null, context, myAbstractMembers);
}
- };
- return !ProgressManager.getInstance().runProcessWithProgressSynchronously(searchConflictsRunnable, RefactoringBundle.message("detecting.possible.conflicts"), false, context.getProject());
+ }
+ RefactoringConflictsUtil.analyzeAccessibilityConflicts(myMovedMembers, targetClass, myConflicts, null, context, myAbstractMembers);
+
}
public void checkMemberPlacementInTargetClassConflict(final PsiClass targetClass, final PsiMember movedMember) {
diff --git a/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownProcessor.java b/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownProcessor.java
index 71b2661..a6cecc7 100644
--- a/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownProcessor.java
@@ -20,6 +20,7 @@
import com.intellij.codeInsight.intention.impl.CreateClassDialog;
import com.intellij.codeInsight.intention.impl.CreateSubclassAction;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
@@ -87,7 +88,7 @@
}
protected boolean preprocessUsages(final Ref<UsageInfo[]> refUsages) {
- UsageInfo[] usagesIn = refUsages.get();
+ final UsageInfo[] usagesIn = refUsages.get();
final PushDownConflicts pushDownConflicts = new PushDownConflicts(myClass, myMemberInfos);
pushDownConflicts.checkSourceClassConflicts();
@@ -115,14 +116,20 @@
} else if (answer != 1) return false;
}
}
- for (UsageInfo usage : usagesIn) {
- final PsiElement element = usage.getElement();
- if (element instanceof PsiClass) {
- boolean canceled = pushDownConflicts.checkTargetClassConflicts((PsiClass)element, usagesIn.length > 1, element);
- if (canceled) return false;
+ Runnable runnable = new Runnable() {
+ public void run() {
+ for (UsageInfo usage : usagesIn) {
+ final PsiElement element = usage.getElement();
+ if (element instanceof PsiClass) {
+ pushDownConflicts.checkTargetClassConflicts((PsiClass)element, usagesIn.length > 1, element);
+ }
+ }
}
- }
+ };
+ if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(runnable, RefactoringBundle.message("detecting.possible.conflicts"), true, myProject)) {
+ return false;
+ }
return showConflicts(pushDownConflicts.getConflicts(), usagesIn);
}
diff --git a/java/java-impl/src/com/intellij/refactoring/migration/MigrationUtil.java b/java/java-impl/src/com/intellij/refactoring/migration/MigrationUtil.java
index 7a1924f..a559a39 100644
--- a/java/java-impl/src/com/intellij/refactoring/migration/MigrationUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/migration/MigrationUtil.java
@@ -48,13 +48,18 @@
// rename all references
for (UsageInfo usage : usages) {
- PsiElement element = usage.getElement();
- if (element == null || !element.isValid()) continue;
- if (element instanceof PsiJavaCodeReferenceElement) {
- ((PsiJavaCodeReferenceElement)element).bindToElement(aPackage);
- }
- else {
- bindNonJavaReference(aPackage, element, usage);
+ if (usage instanceof MigrationProcessor.MigrationUsageInfo) {
+ final MigrationProcessor.MigrationUsageInfo usageInfo = (MigrationProcessor.MigrationUsageInfo)usage;
+ if (Comparing.equal(newQName, usageInfo.mapEntry.getNewName())) {
+ PsiElement element = usage.getElement();
+ if (element == null || !element.isValid()) continue;
+ if (element instanceof PsiJavaCodeReferenceElement) {
+ ((PsiJavaCodeReferenceElement)element).bindToElement(aPackage);
+ }
+ else {
+ bindNonJavaReference(aPackage, element, usage);
+ }
+ }
}
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java
index 38fa2e6..8322228 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java
@@ -31,7 +31,6 @@
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.file.JavaDirectoryServiceImpl;
-import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.RefactoringBundle;
@@ -81,12 +80,12 @@
final PsiClass[] classes = ((PsiClassOwner)element).getClasses();
if (classes.length == 0) return true;
for (PsiClass aClass : classes) {
- if (aClass instanceof JspClass) return true;
+ if (aClass instanceof PsiSyntheticClass) return true;
}
parentFile = (PsiFile)element;
}
else {
- if (element instanceof JspClass) return true;
+ if (element instanceof PsiSyntheticClass) return true;
if (!(element instanceof PsiClass)) return true;
if (element instanceof PsiAnonymousClass) return true;
if (((PsiClass)element).getContainingClass() != null) return true;
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodHandlerDelegate.java b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodHandlerDelegate.java
index acf48b7..314666c 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodHandlerDelegate.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodHandlerDelegate.java
@@ -15,27 +15,28 @@
*/
package com.intellij.refactoring.move.moveInstanceMethod;
-import com.intellij.psi.*;
-import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
-import com.intellij.refactoring.move.MoveHandlerDelegate;
-import com.intellij.refactoring.move.MoveCallback;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.refactoring.move.MoveCallback;
+import com.intellij.refactoring.move.MoveHandlerDelegate;
import com.intellij.refactoring.move.moveClassesOrPackages.JavaMoveClassesOrPackagesHandler;
import org.jetbrains.annotations.Nullable;
public class MoveInstanceMethodHandlerDelegate extends MoveHandlerDelegate {
+ @Override
public boolean canMove(final PsiElement[] elements, @Nullable final PsiElement targetContainer) {
if (elements.length != 1) return false;
PsiElement element = elements [0];
if (!(element instanceof PsiMethod)) return false;
- if (element instanceof JspHolderMethod) return false;
+ if (element instanceof SyntheticElement) return false;
PsiMethod method = (PsiMethod) element;
if (method.hasModifierProperty(PsiModifier.STATIC)) return false;
return super.canMove(elements, targetContainer);
}
+ @Override
public boolean isValidTarget(final PsiElement psiElement, PsiElement[] sources) {
for (PsiElement source : sources) {
if (JavaMoveClassesOrPackagesHandler.invalid4Move(source)) return false;
@@ -43,6 +44,7 @@
return psiElement instanceof PsiClass && !(psiElement instanceof PsiAnonymousClass);
}
+ @Override
public boolean tryToMove(final PsiElement element, final Project project, final DataContext dataContext, final PsiReference reference,
final Editor editor) {
if (element instanceof PsiMethod) {
@@ -55,6 +57,7 @@
return false;
}
+ @Override
public void doMove(final Project project, final PsiElement[] elements, final PsiElement targetContainer, final MoveCallback callback) {
new MoveInstanceMethodHandler().invoke(project, elements, null);
}
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersHandler.java
index 16c3c33..077963f 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersHandler.java
@@ -19,7 +19,6 @@
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
import com.intellij.refactoring.move.MoveCallback;
import com.intellij.refactoring.move.MoveHandlerDelegate;
import org.jetbrains.annotations.Nullable;
@@ -52,7 +51,7 @@
private static boolean isFieldOrStaticMethod(final PsiElement element) {
if (element instanceof PsiField) return true;
if (element instanceof PsiMethod) {
- if (element instanceof JspHolderMethod) return false;
+ if (element instanceof SyntheticElement) return false;
return ((PsiMethod) element).hasModifierProperty(PsiModifier.STATIC);
}
return false;
diff --git a/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java b/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java
index d60d08d..1f9d9f8 100644
--- a/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java
+++ b/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java
@@ -22,23 +22,30 @@
import com.intellij.codeInsight.generation.PsiGenerationInfo;
import com.intellij.codeInsight.generation.actions.BaseGenerateAction;
import com.intellij.codeInsight.hint.HintManager;
+import com.intellij.ide.fileTemplates.FileTemplateDescriptor;
+import com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable;
+import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.ui.components.JBList;
+import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
public class BaseGenerateTestSupportMethodAction extends BaseGenerateAction {
@@ -48,13 +55,46 @@
super(new MyHandler(methodKind));
}
+ @Nullable
+ @Override
+ public AnAction createEditTemplateAction(DataContext dataContext) {
+ final Project project = PlatformDataKeys.PROJECT.getData(dataContext);
+ final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
+ final PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext);
+ final PsiClass targetClass = editor == null || file == null ? null : getTargetClass(editor, file);
+ if (targetClass != null) {
+ final List<TestFramework> frameworks = TestIntegrationUtils.findSuitableFrameworks(targetClass);
+ final TestIntegrationUtils.MethodKind methodKind = ((MyHandler)getHandler()).myMethodKind;
+ if (!frameworks.isEmpty()) {
+ return new AnAction("Edit Template") {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ chooseAndPerform(editor, frameworks, new Consumer<TestFramework>() {
+ @Override
+ public void consume(TestFramework framework) {
+ final FileTemplateDescriptor descriptor = methodKind.getFileTemplateDescriptor(framework);
+ if (descriptor != null) {
+ final String fileName = descriptor.getFileName();
+ AllFileTemplatesConfigurable.editCodeTemplate(FileUtil.getNameWithoutExtension(fileName), project);
+ } else {
+ HintManager.getInstance().showErrorHint(editor, "No template found for " + framework.getName() + ":" + BaseGenerateTestSupportMethodAction.this.getTemplatePresentation().getText());
+ }
+ }
+ });
+ }
+ };
+ }
+ }
+ return null;
+ }
+
@Override
protected PsiClass getTargetClass(Editor editor, PsiFile file) {
return findTargetClass(editor, file);
}
@Nullable
- private static PsiClass findTargetClass(Editor editor, PsiFile file) {
+ private static PsiClass findTargetClass(@NotNull Editor editor, @NotNull PsiFile file) {
int offset = editor.getCaretModel().getOffset();
PsiElement element = file.findElementAt(offset);
return element == null ? null : TestIntegrationUtils.findOuterClass(element);
@@ -86,6 +126,47 @@
return true;
}
+ private static void chooseAndPerform(Editor editor, List<TestFramework> frameworks, final Consumer<TestFramework> consumer) {
+ if (frameworks.size() == 1) {
+ consumer.consume(frameworks.get(0));
+ return;
+ }
+
+ final JList list = new JBList(frameworks.toArray(new TestFramework[frameworks.size()]));
+ list.setCellRenderer(new DefaultListCellRenderer() {
+ @Override
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ Component result = super.getListCellRendererComponent(list, "", index, isSelected, cellHasFocus);
+ if (value == null) return result;
+ TestFramework framework = (TestFramework)value;
+
+ setIcon(framework.getIcon());
+ setText(framework.getName());
+
+ return result;
+ }
+ });
+
+
+ PopupChooserBuilder builder = new PopupChooserBuilder(list);
+ builder.setFilteringEnabled(new Function<Object, String>() {
+ @Override
+ public String fun(Object o) {
+ return ((TestFramework)o).getName();
+ }
+ });
+
+ builder
+ .setTitle("Choose Framework")
+ .setItemChoosenCallback(new Runnable() {
+ @Override
+ public void run() {
+ consumer.consume((TestFramework)list.getSelectedValue());
+ }
+ })
+ .setMovable(true)
+ .createPopup().showInBestPositionFor(editor);
+ }
private static class MyHandler implements CodeInsightActionHandler {
private TestIntegrationUtils.MethodKind myMethodKind;
@@ -97,51 +178,24 @@
public void invoke(@NotNull Project project, @NotNull final Editor editor, @NotNull final PsiFile file) {
final PsiClass targetClass = findTargetClass(editor, file);
final List<TestFramework> frameworks = TestIntegrationUtils.findSuitableFrameworks(targetClass);
- if (frameworks.isEmpty()) return;
-
- if (frameworks.size() == 1) {
- doGenerate(editor, file, targetClass, frameworks.get(0));
- return;
- }
-
- final JList list = new JBList(frameworks.toArray(new TestFramework[frameworks.size()]));
- list.setCellRenderer(new DefaultListCellRenderer() {
- @Override
- public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
- Component result = super.getListCellRendererComponent(list, "", index, isSelected, cellHasFocus);
- if (value == null) return result;
- TestFramework framework = (TestFramework)value;
-
- setIcon(framework.getIcon());
- setText(framework.getName());
-
- return result;
+ for (Iterator<TestFramework> iterator = frameworks.iterator(); iterator.hasNext(); ) {
+ if (myMethodKind.getFileTemplateDescriptor(iterator.next()) == null) {
+ iterator.remove();
}
- });
-
- final Runnable runnable = new Runnable() {
- public void run() {
- TestFramework selected = (TestFramework)list.getSelectedValue();
- if (selected == null) return;
- doGenerate(editor, file, targetClass, selected);
+ }
+ if (frameworks.isEmpty()) return;
+ final Consumer<TestFramework> consumer = new Consumer<TestFramework>() {
+ @Override
+ public void consume(TestFramework framework) {
+ if (framework == null) return;
+ doGenerate(editor, file, targetClass, framework);
}
};
- PopupChooserBuilder builder = new PopupChooserBuilder(list);
- builder.setFilteringEnabled(new Function<Object, String>() {
- @Override
- public String fun(Object o) {
- return ((TestFramework)o).getName();
- }
- });
-
- builder
- .setTitle("Choose Framework")
- .setItemChoosenCallback(runnable)
- .setMovable(true)
- .createPopup().showInBestPositionFor(editor);
+ chooseAndPerform(editor, frameworks, consumer);
}
+
private void doGenerate(final Editor editor, final PsiFile file, final PsiClass targetClass, final TestFramework framework) {
if (!CommonRefactoringUtil.checkReadOnlyStatus(file)) return;
diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/ClassGroupingRule.java b/java/java-impl/src/com/intellij/usages/impl/rules/ClassGroupingRule.java
index b4f6127..add3fe2 100644
--- a/java/java-impl/src/com/intellij/usages/impl/rules/ClassGroupingRule.java
+++ b/java/java-impl/src/com/intellij/usages/impl/rules/ClassGroupingRule.java
@@ -25,7 +25,6 @@
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.jsp.JspFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.usages.Usage;
@@ -53,7 +52,7 @@
PsiFile topLevelFile = InjectedLanguageManager.getInstance(containingFile.getProject()).getTopLevelFile(containingFile);
- if (!(topLevelFile instanceof PsiJavaFile) || topLevelFile instanceof JspFile) {
+ if (!(topLevelFile instanceof PsiJavaFile) || topLevelFile instanceof ServerPageFile) {
return null;
}
PsiElement containingClass = topLevelFile == containingFile ? psiElement : InjectedLanguageManager
diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/NonJavaFileGroupingRule.java b/java/java-impl/src/com/intellij/usages/impl/rules/NonJavaFileGroupingRule.java
index 90be2e8..f18012d 100644
--- a/java/java-impl/src/com/intellij/usages/impl/rules/NonJavaFileGroupingRule.java
+++ b/java/java-impl/src/com/intellij/usages/impl/rules/NonJavaFileGroupingRule.java
@@ -18,7 +18,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
-import com.intellij.psi.jsp.JspFile;
+import com.intellij.psi.ServerPageFile;
import com.intellij.usages.Usage;
import com.intellij.usages.UsageGroup;
import org.jetbrains.annotations.NotNull;
@@ -28,11 +28,12 @@
super(project);
}
+ @Override
public UsageGroup groupUsage(@NotNull Usage usage) {
final FileUsageGroup usageGroup = (FileUsageGroup)super.groupUsage(usage);
if (usageGroup != null) {
final PsiFile psiFile = usageGroup.getPsiFile();
- if (psiFile instanceof PsiJavaFile && !(psiFile instanceof JspFile)) {
+ if (psiFile instanceof PsiJavaFile && !(psiFile instanceof ServerPageFile)) {
return null;
}
}
diff --git a/java/java-impl/src/com/intellij/util/xml/impl/ExtendsClassChecker.java b/java/java-impl/src/com/intellij/util/xml/impl/ExtendsClassChecker.java
index 128bd56..0fd831c 100644
--- a/java/java-impl/src/com/intellij/util/xml/impl/ExtendsClassChecker.java
+++ b/java/java-impl/src/com/intellij/util/xml/impl/ExtendsClassChecker.java
@@ -22,6 +22,7 @@
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.xml.XmlElement;
import com.intellij.util.ProcessingContext;
import com.intellij.util.ReflectionCache;
import com.intellij.util.SmartList;
@@ -142,7 +143,10 @@
final Object valueObject = element.getValue();
if (!(valueObject instanceof PsiClass)) return Collections.emptyList();
- final PsiReference[] references = ourProvider.getReferencesByElement(DomUtil.getValueElement(element), new ProcessingContext());
+ final XmlElement valueElement = DomUtil.getValueElement(element);
+ if (valueElement == null) return Collections.emptyList();
+
+ final PsiReference[] references = ourProvider.getReferencesByElement(valueElement, new ProcessingContext());
for (PsiReference reference : references) {
if (reference instanceof JavaClassReference) {
final PsiReferenceProvider psiReferenceProvider = ((JavaClassReference)reference).getProvider();
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java b/java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java
index 38465bd..6854c57 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/PsiShortNamesCache.java
@@ -20,9 +20,11 @@
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
+import com.intellij.util.indexing.IdFilter;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -89,6 +91,10 @@
return ContainerUtil.process(getAllClassNames(), processor);
}
+ public boolean processAllClassNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+ return ContainerUtil.process(getAllClassNames(), processor);
+ }
+
/**
* Adds the names of all classes in the project and (optionally) libraries
* to the specified set.
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java b/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java
index 52d5801..e6ba22d 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java
@@ -27,6 +27,7 @@
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
+import com.intellij.util.indexing.IdFilter;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -106,6 +107,16 @@
}
@Override
+ public boolean processAllClassNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+ for (PsiShortNamesCache cache : myCaches) {
+ if (!cache.processAllClassNames(processor, scope, filter)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
public void getAllClassNames(@NotNull HashSet<String> dest) {
for (PsiShortNamesCache cache : myCaches) {
cache.getAllClassNames(dest);
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java b/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java
index b17c4b1..e702d01 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java
@@ -32,6 +32,8 @@
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.containers.HashSet;
+import com.intellij.util.indexing.FileBasedIndex;
+import com.intellij.util.indexing.IdFilter;
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NonNls;
@@ -115,6 +117,11 @@
}
@Override
+ public boolean processAllClassNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+ return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.CLASS_SHORT_NAMES, processor, scope, filter);
+ }
+
+ @Override
@NotNull
public PsiMethod[] getMethodsByName(@NotNull String name, @NotNull final GlobalSearchScope scope) {
Collection<PsiMethod> methods = StubIndex.getInstance().get(JavaStubIndexKeys.METHODS, name, myManager.getProject(), new JavaSourceFilterScope(scope));
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaShortClassNameIndex.java b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaShortClassNameIndex.java
index 7faeaf9..95e27ea 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaShortClassNameIndex.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaShortClassNameIndex.java
@@ -26,6 +26,7 @@
import com.intellij.psi.stubs.StringStubIndexExtension;
import com.intellij.psi.stubs.StubIndex;
import com.intellij.psi.stubs.StubIndexKey;
+import com.intellij.util.indexing.FileBasedIndex;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@@ -33,10 +34,16 @@
public class JavaShortClassNameIndex extends StringStubIndexExtension<PsiClass> {
private static final JavaShortClassNameIndex ourInstance = new JavaShortClassNameIndex();
+
public static JavaShortClassNameIndex getInstance() {
return ourInstance;
}
+ @Override
+ public int getVersion() {
+ return super.getVersion() + (FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping ? 1 : 0);
+ }
+
@NotNull
@Override
public StubIndexKey<String, PsiClass> getKey() {
@@ -47,4 +54,9 @@
public Collection<PsiClass> get(final String s, final Project project, @NotNull final GlobalSearchScope scope) {
return StubIndex.getInstance().safeGet(getKey(), s, project, new JavaSourceFilterScope(scope), PsiClass.class);
}
+
+ @Override
+ public boolean traceKeyHashToVirtualFileMapping() {
+ return FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping;
+ }
}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInsight/ClassUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/ClassUtil.java
similarity index 100%
rename from java/openapi/src/com/intellij/codeInsight/ClassUtil.java
rename to java/java-psi-api/src/com/intellij/codeInsight/ClassUtil.java
diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java
index a00e880..b30f262 100644
--- a/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java
@@ -15,6 +15,7 @@
*/
package com.intellij.psi;
+import com.intellij.openapi.util.Computable;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
@@ -58,8 +59,13 @@
}
} else if (functionalInterfaceReturnType != null) {
final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions(lambdaExpression);
- for (PsiExpression expression : returnExpressions) {
- final PsiType expressionType = expression.getType();
+ for (final PsiExpression expression : returnExpressions) {
+ final PsiType expressionType = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(expression, true, new Computable<PsiType>() {
+ @Override
+ public PsiType compute() {
+ return expression.getType();
+ }
+ });
if (expressionType != null && !functionalInterfaceReturnType.isAssignableFrom(expressionType)) {
return "Incompatible return type " + expressionType.getPresentableText() + " in lambda expression";
}
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 41c4aa5..2bfe470 100644
--- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
@@ -711,9 +711,9 @@
}
}
- final PsiClassType.ClassResolveResult r = PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(returnType));
+ final PsiClassType.ClassResolveResult r = PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(returnType, false));
final PsiClass rClass = r.getElement();
- final PsiClassType.ClassResolveResult r1 = PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(returnType1));
+ final PsiClassType.ClassResolveResult r1 = PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(returnType1, false));
final PsiClass rClass1 = r1.getElement();
if (rClass != null && rClass1 != null) {
if (rClass == rClass1) {
@@ -722,13 +722,13 @@
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 (t1.isAssignableFrom(t)) {
if (moreSpecific == 1) {
return 0;
}
moreSpecific = -1;
}
- else if (t.isAssignableFrom(t1) && !GenericsUtil.eliminateWildcards(t).equals(t1)) {
+ else if (t.isAssignableFrom(t1)) {
if (moreSpecific == -1) {
return 0;
}
diff --git a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java
index 4b2b4da..756543d 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java
@@ -82,8 +82,12 @@
final PsiParameter[] parameters = method.getParameterList().getParameters();
PsiType[] parameterTypes = new PsiType[parameters.length];
for (int i = 0; i < parameterTypes.length; i++) {
- PsiType type = parameters[i].getType();
+ PsiParameter parameter = parameters[i];
+ PsiType type = parameter.getType();
parameterTypes[i] = isRaw ? TypeConversionUtil.erasure(substitutor.substitute(type)) : type;
+ if (!parameterTypes[i].isValid()) {
+ PsiUtil.ensureValidType(parameterTypes[i], "Method " + method + " of " + method.getClass() + "; param " + parameter + " of " + parameter.getClass());
+ }
}
return new MethodSignatureBackedByPsiMethod(method, substitutor, isRaw, parameterTypes, methodTypeParameters);
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 3d6f4c7..abe33b5 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
@@ -355,7 +355,7 @@
return buffer.toString();
}
- public static String formatType(PsiType type, int options, @NotNull PsiSubstitutor substitutor){
+ public static String formatType(@Nullable PsiType type, int options, @NotNull PsiSubstitutor substitutor){
type = substitutor.substitute(type);
if ((options & SHOW_RAW_TYPE) != 0) {
type = TypeConversionUtil.erasure(type);
@@ -368,6 +368,7 @@
}
}
}
+ if (type == null) return "null";
return (options & SHOW_FQ_CLASS_NAMES) == 0 ? type.getPresentableText() : type.getInternalCanonicalText();
}
diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiMethodUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiMethodUtil.java
index d0b3dc9..d241e3f 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/PsiMethodUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/PsiMethodUtil.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.
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.intellij.psi.util;
import com.intellij.openapi.util.Condition;
@@ -26,7 +25,6 @@
* @author mike
*/
public class PsiMethodUtil {
-
private static final JavaMainMethodProvider[] myProviders = Extensions.getExtensions(JavaMainMethodProvider.EP_NAME);
public static final Condition<PsiClass> MAIN_CLASS = new Condition<PsiClass>() {
@@ -38,8 +36,7 @@
}
};
- private PsiMethodUtil() {
- }
+ private PsiMethodUtil() { }
@Nullable
public static PsiMethod findMainMethod(final PsiClass aClass) {
@@ -70,7 +67,7 @@
final PsiType type = parameters[0].getType();
if (!(type instanceof PsiArrayType)) return false;
final PsiType componentType = ((PsiArrayType)type).getComponentType();
- return componentType.equalsToText("java.lang.String");
+ return componentType.equalsToText(CommonClassNames.JAVA_LANG_STRING);
}
public static boolean hasMainMethod(final PsiClass psiClass) {
diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
index 642d855..7cedb1d 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
@@ -1028,16 +1028,24 @@
}
public static void ensureValidType(@NotNull PsiType type) {
+ ensureValidType(type, null);
+ }
+ public static void ensureValidType(@NotNull PsiType type, @Nullable String customMessage) {
if (!type.isValid()) {
TimeoutUtil.sleep(1); // to see if processing in another thread suddenly makes the type valid again (which is a bug)
if (type.isValid()) {
- LOG.error("PsiType resurrected: " + type + " of " + type.getClass());
+ LOG.error("PsiType resurrected: " + type + " of " + type.getClass() + " " + customMessage);
return;
}
if (type instanceof PsiClassType) {
- ((PsiClassType)type).resolve(); // should throw exception
+ try {
+ ((PsiClassType)type).resolve(); // should throw exception
+ }
+ catch (PsiInvalidElementAccessException e) {
+ throw customMessage == null? e : new RuntimeException(customMessage, e);
+ }
}
- throw new AssertionError("Invalid type: " + type + " of class " + type.getClass());
+ throw new AssertionError("Invalid type: " + type + " of class " + type.getClass() + " " + customMessage);
}
}
diff --git a/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java b/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java
index 91af96d..f3a325a 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java
@@ -523,7 +523,8 @@
}
}
}
- if (parent instanceof PsiInstanceOfExpression || TypeConversionUtil.isAssignable(castTo, opType, false)) {
+ if (parent instanceof PsiInstanceOfExpression || (TypeConversionUtil.isAssignable(castTo, opType, false) &&
+ (expectedTypeByParent == null || TypeConversionUtil.isAssignable(expectedTypeByParent, opType, false)))) {
addToResults(typeCast);
}
}
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 2a7ba4f..7887f0d 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
@@ -893,9 +893,6 @@
PsiSubstitutor leftSubstitutor = leftResult.getSubstitutor();
if (!leftClass.getManager().areElementsEquivalent(leftClass, rightClass)) {
- if (!allowUncheckedConversion && PsiUtil.isRawSubstitutor(leftClass, leftSubstitutor) && !rightClass.hasTypeParameters() && !(rightClass instanceof PsiTypeParameter)) {
- return false;
- }
rightSubstitutor = getSuperClassSubstitutor(leftClass, rightClass, rightSubstitutor);
rightClass = leftClass;
}
diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java
index 1ada9aa..080ef4a 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java
@@ -126,6 +126,8 @@
final PsiClass boundClass1 = PsiUtil.resolveClassInType(extendsBound1);
final PsiClass boundClass2 = PsiUtil.resolveClassInType(extendsBound2);
if (boundClass1 != null && boundClass2 != null) {
+ if (extendsBound1 instanceof PsiClassType && extendsBound2 instanceof PsiClassType &&
+ (((PsiClassType)extendsBound1).isRaw() ^ ((PsiClassType)extendsBound2).isRaw())) return true;
return proveExtendsBoundsDistinct(type1, type2, boundClass1, boundClass2);
}
return provablyDistinct(extendsBound1, extendsBound2, 1);
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 8d75564..464c01b 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
@@ -21,6 +21,7 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.LowMemoryWatcher;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -56,6 +57,14 @@
private final ConcurrentMap<String, List<PsiFile>> myExternalAnnotations = new ConcurrentSoftValueHashMap<String, List<PsiFile>>(10, 0.75f, 2);
protected final PsiManager myPsiManager;
+ @SuppressWarnings("UnusedDeclaration")
+ private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() {
+ @Override
+ public void run() {
+ dropCache();
+ }
+ });
+
public BaseExternalAnnotationsManager(final PsiManager psiManager) {
myPsiManager = psiManager;
}
@@ -215,7 +224,8 @@
}
protected void duplicateError(@NotNull PsiFile file, @NotNull String externalName, @NotNull String text) {
- LOG.error(text + "; for signature: '" + externalName + "' in the file " + file.getVirtualFile().getPresentableUrl());
+ VirtualFile virtualFile = file.getVirtualFile();
+ LOG.error(text + "; for signature: '" + externalName + "' in the file " + (virtualFile != null ? virtualFile.getPresentableUrl() : null));
}
@NotNull
@@ -406,7 +416,7 @@
@NotNull private final String annotationClassFqName;
@NotNull private final String annotationParameters;
private final VirtualFile virtualFile;
- private PsiAnnotation annotation;
+ private volatile PsiAnnotation annotation;
private AnnotationData(@NotNull String annotationClassFqName, @NotNull String annotationParameters, VirtualFile virtualFile) {
this.annotationClassFqName = annotationClassFqName;
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/FileParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/FileParser.java
index eeee9777..6b9f154 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/parser/FileParser.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/FileParser.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.
@@ -55,19 +55,14 @@
@NotNull final String errorMessageKey) {
parsePackageStatement(builder);
- final Pair<PsiBuilder.Marker, Boolean> impListInfo = parseImportList(builder, importListStoppers);
+ Pair<PsiBuilder.Marker, Boolean> impListInfo = parseImportList(builder, importListStoppers);
Boolean firstDeclarationOk = null;
PsiBuilder.Marker firstDeclaration = null;
PsiBuilder.Marker invalidElements = null;
while (!builder.eof()) {
if (builder.getTokenType() == JavaTokenType.SEMICOLON) {
- if (invalidElements != null) {
- invalidElements.error(error(bundle, errorMessageKey));
- invalidElements = null;
- }
builder.advanceLexer();
- if (firstDeclarationOk == null) firstDeclarationOk = false;
continue;
}
@@ -124,7 +119,7 @@
final PsiBuilder.Marker ref = myParser.getReferenceParser().parseJavaCodeReference(builder, true, false, false, false);
if (ref == null) {
- statement.rollbackTo();
+ statement.error(JavaErrorMessages.message("expected.class.or.interface"));
return null;
}
@@ -136,13 +131,21 @@
@NotNull
public Pair<PsiBuilder.Marker, Boolean> parseImportList(final PsiBuilder builder, final TokenSet stoppers) {
- final PsiBuilder.Marker list = builder.mark();
+ PsiBuilder.Marker list = builder.mark();
- final boolean isEmpty = builder.getTokenType() != JavaTokenType.IMPORT_KEYWORD;
+ IElementType tokenType = builder.getTokenType();
+ boolean isEmpty = tokenType != JavaTokenType.IMPORT_KEYWORD && tokenType != JavaTokenType.SEMICOLON;
if (!isEmpty) {
PsiBuilder.Marker invalidElements = null;
while (!builder.eof()) {
- if (stoppers.contains(builder.getTokenType())) break;
+ tokenType = builder.getTokenType();
+ if (stoppers.contains(tokenType)) {
+ break;
+ }
+ else if (tokenType == JavaTokenType.SEMICOLON) {
+ builder.advanceLexer();
+ continue;
+ }
final PsiBuilder.Marker statement = parseImportStatement(builder);
if (statement != null) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java
index a5aed98..3850cea 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java
@@ -19,6 +19,7 @@
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -217,14 +218,14 @@
pineBuffer.append('<');
for (int i = 0; i < typeParameters.length; i++) {
PsiTypeParameter typeParameter = typeParameters[i];
- assert typeParameter.isValid();
+ PsiUtilCore.ensureValid(typeParameter);
if (i > 0) pineBuffer.append(',');
final PsiType substitutionResult = substitutor.substitute(typeParameter);
if (substitutionResult == null) {
pineBuffer = null;
break;
}
- assert substitutionResult.isValid();
+ PsiUtil.ensureValidType(substitutionResult);
if (canonical) {
if (internal) {
pineBuffer.append(substitutionResult.getInternalCanonicalText());
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 48a0e09..bc62cc8 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
@@ -44,6 +44,7 @@
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -91,7 +92,7 @@
}
public int getKind() {
- LOG.assertTrue(isValid());
+ PsiUtilCore.ensureValid(this);
CompositeElement treeParent = getTreeParent();
IElementType i = treeParent.getElementType();
if (isDummy(i)) {
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 bbe39b3..6410991 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
@@ -1199,6 +1199,7 @@
PsiType[] superTypes = typeParameter.getSuperTypes();
if (superTypes.length == 0) return null;
+ final PsiType[] types = new PsiType[superTypes.length];
for (int i = 0; i < superTypes.length; i++) {
PsiType superType = substitutor.substitute(superTypes[i]);
if (superType instanceof PsiClassType && ((PsiClassType)superType).isRaw()) {
@@ -1206,9 +1207,9 @@
}
if (superType == null) superType = PsiType.getJavaLangObject(myManager, scope);
if (superType == null) return null;
- superTypes[i] = superType;
+ types[i] = superType;
}
- return policy.getInferredTypeWithNoConstraint(myManager, PsiIntersectionType.createIntersection(superTypes));
+ return policy.getInferredTypeWithNoConstraint(myManager, PsiIntersectionType.createIntersection(types));
}
return null;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java
index f397423..27012ff 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java
@@ -97,6 +97,7 @@
if (type2 == null) return null;
}
+ if (type1 instanceof PsiLambdaParameterType || type2 instanceof PsiLambdaParameterType) return null;
final PsiType leastUpperBound = GenericsUtil.getLeastUpperBound(type1, type2, getManager());
return leastUpperBound != null ? PsiUtil.captureToplevelWildcards(leastUpperBound, this) : null;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
index 2cd3f29..4c799c6 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
@@ -393,7 +393,7 @@
}
private PsiSubstitutor getSubstitutor(PsiType type) {
- final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(type);
+ final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(type));
PsiSubstitutor psiSubstitutor = resolveResult.getSubstitutor();
if (type instanceof PsiClassType) {
final PsiClass psiClass = resolveResult.getElement();
diff --git a/java/java-tests/java-tests.iml b/java/java-tests/java-tests.iml
index cc0afca..ef3e588 100644
--- a/java/java-tests/java-tests.iml
+++ b/java/java-tests/java-tests.iml
@@ -30,6 +30,7 @@
<orderEntry type="module" module-name="java-indexing-api" scope="TEST" />
<orderEntry type="module" module-name="external-system-impl" scope="RUNTIME" />
<orderEntry type="module" module-name="junit_rt" scope="TEST" />
+ <orderEntry type="module" module-name="manifest" scope="TEST" />
</component>
</module>
diff --git a/java/java-tests/testData/codeInsight/completeStatement/MultilineCall.java b/java/java-tests/testData/codeInsight/completeStatement/MultilineCall.java
new file mode 100644
index 0000000..dfcca36
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completeStatement/MultilineCall.java
@@ -0,0 +1,6 @@
+class Test {
+ Object method() {
+ method(
+ factory()<caret>
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completeStatement/MultilineCall_after.java b/java/java-tests/testData/codeInsight/completeStatement/MultilineCall_after.java
new file mode 100644
index 0000000..1d2e3fc
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completeStatement/MultilineCall_after.java
@@ -0,0 +1,6 @@
+class Test {
+ Object method() {
+ method(
+ factory());<caret>
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/DelegatingConstructorCall.java b/java/java-tests/testData/codeInsight/completion/normalSorting/DelegatingConstructorCall.java
new file mode 100644
index 0000000..a9849ac
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normalSorting/DelegatingConstructorCall.java
@@ -0,0 +1,12 @@
+class SearchParameters {
+
+ public SearchParameters(PsiElement element) {
+ this(e<caret>);
+ }
+
+ public SearchParameters(final PsiElement element, final boolean checkDeep) {
+ }
+
+}
+
+class PsiElement {}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA97276.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA97276.java
index c059e83..625d706 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA97276.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA97276.java
@@ -2,3 +2,16 @@
class SomeClass {
static <I extends Interf<? super I>> Class<I> someMethod(I i) { return null; }
}
+
+interface OtherInterf<I1 extends Interf, I2 extends Interf> {}
+interface ImmutableSet<S> {}
+
+class SomeOtherClass {
+ static ImmutableSet<Class<? extends OtherInterf<?, ?>>> someOtherMethod() {
+ return <error descr="Inconvertible types; cannot cast 'ImmutableSet<java.lang.Class<? extends OtherInterf>>' to 'ImmutableSet<java.lang.Class<? extends OtherInterf<?,?>>>'">(ImmutableSet<Class<? extends OtherInterf<?, ?>>>)aux(OtherInterf.class)</error>;
+ }
+
+ static <T> ImmutableSet<Class<? extends T>> aux(Class<T> t) {
+ return null;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/RawAssignments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/RawAssignments.java
new file mode 100644
index 0000000..bfbe439
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/RawAssignments.java
@@ -0,0 +1,18 @@
+import java.io.*;
+import java.util.*;
+
+interface Foo {
+ String getText(Map attributes) throws IOException;
+ String getText(Properties attributes) throws IOException;
+}
+
+class Bar {
+ void foo(Foo foo, Properties prop) throws IOException {
+ foo.getText(prop);
+ }
+}
+public abstract class Hashtable<K,V> implements Map<K,V>, Cloneable {
+}
+
+public abstract class Properties extends Hashtable<Object,Object> {
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/IDEA112323.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/IDEA112323.java
new file mode 100644
index 0000000..95e8fcf
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/IDEA112323.java
@@ -0,0 +1,17 @@
+import java.util.*;
+interface Stream<T> {
+ <R> Stream<R> map(Function<? super T, ? extends R> mapper);
+}
+
+interface Function<T, R> {
+ R apply(T t);
+}
+
+class Test1
+{
+ public static void main(Stream<Map.Entry<String, Long>> stream)
+ {
+ Stream<String> map = stream.map(Map.Entry::getKey);
+ }
+
+}
diff --git a/java/java-tests/testData/psi/parser-partial/files/ExtraSemicolons.txt b/java/java-tests/testData/psi/parser-partial/files/ExtraSemicolons.txt
new file mode 100644
index 0000000..d761853
--- /dev/null
+++ b/java/java-tests/testData/psi/parser-partial/files/ExtraSemicolons.txt
@@ -0,0 +1,37 @@
+PsiJavaFile:ExtraSemicolons.java
+ PsiPackageStatement:p
+ PsiKeyword:package('package')
+ PsiWhiteSpace(' ')
+ PsiJavaCodeReferenceElement:p
+ PsiIdentifier:p('p')
+ PsiReferenceParameterList
+ <empty list>
+ PsiJavaToken:SEMICOLON(';')
+ PsiImportList
+ PsiJavaToken:SEMICOLON(';')
+ PsiWhiteSpace('\n')
+ PsiImportStatement
+ PsiKeyword:import('import')
+ PsiWhiteSpace(' ')
+ PsiJavaCodeReferenceElement:a
+ PsiIdentifier:a('a')
+ PsiReferenceParameterList
+ <empty list>
+ PsiJavaToken:SEMICOLON(';')
+ PsiJavaToken:SEMICOLON(';')
+ PsiWhiteSpace('\n')
+ PsiClass:C
+ PsiModifierList:
+ <empty list>
+ PsiKeyword:class('class')
+ PsiWhiteSpace(' ')
+ PsiIdentifier:C('C')
+ PsiTypeParameterList
+ <empty list>
+ PsiReferenceList
+ <empty list>
+ PsiReferenceList
+ <empty list>
+ PsiJavaToken:LBRACE('{')
+ PsiJavaToken:RBRACE('}')
+ PsiJavaToken:SEMICOLON(';')
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-partial/files/UnclosedPackage0.txt b/java/java-tests/testData/psi/parser-partial/files/UnclosedPackage0.txt
index cc9866b..bd210ad 100644
--- a/java/java-tests/testData/psi/parser-partial/files/UnclosedPackage0.txt
+++ b/java/java-tests/testData/psi/parser-partial/files/UnclosedPackage0.txt
@@ -1,5 +1,5 @@
PsiJavaFile:UnclosedPackage0.java
- PsiImportList
- <empty list>
PsiErrorElement:'class' or 'interface' expected
- PsiKeyword:package('package')
\ No newline at end of file
+ PsiKeyword:package('package')
+ PsiImportList
+ <empty list>
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/extractMethod/Expression.java b/java/java-tests/testData/refactoring/extractMethod/Expression.java
new file mode 100644
index 0000000..452a7b9
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethod/Expression.java
@@ -0,0 +1,35 @@
+public class AnnotationArgConverter {
+ public GrAnnotationMemberValue convert(PsiAnnotationMemberValue value) {
+ final StringBuilder buffer = new StringBuilder();
+
+ buffer.append("@A(");
+
+ <selection>value.accept(new JavaElementVisitor() {
+ @Override
+ public void visitExpression(PsiExpression expression) {
+ buffer.append(expression.getText());
+ }
+
+ @Override
+ public void visitNewExpression(PsiNewExpression expression) {
+ PsiArrayInitializerExpression arrayInitializer = expression.getArrayInitializer();
+ if (arrayInitializer == null) {
+ super.visitNewExpression(expression);
+ }
+ else {
+ buffer.append(")");
+ }
+ }
+
+ })</selection>;
+
+ buffer.append(")");
+
+ try {
+ return GroovyPsiElementFactory.getInstance(value.getProject()).createAnnotationFromText(buffer.toString());
+ }
+ catch (IncorrectOperationException e) {
+ return null;
+ }
+ }
+}
diff --git a/java/java-tests/testData/refactoring/extractMethod/Expression_after.java b/java/java-tests/testData/refactoring/extractMethod/Expression_after.java
new file mode 100644
index 0000000..03f1402
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethod/Expression_after.java
@@ -0,0 +1,39 @@
+public class AnnotationArgConverter {
+ public GrAnnotationMemberValue convert(PsiAnnotationMemberValue value) {
+ final StringBuilder buffer = new StringBuilder();
+
+ buffer.append("@A(");
+
+ newMethod(value, buffer);
+
+ buffer.append(")");
+
+ try {
+ return GroovyPsiElementFactory.getInstance(value.getProject()).createAnnotationFromText(buffer.toString());
+ }
+ catch (IncorrectOperationException e) {
+ return null;
+ }
+ }
+
+ private void newMethod(PsiAnnotationMemberValue value, final StringBuilder buffer) {
+ value.accept(new JavaElementVisitor() {
+ @Override
+ public void visitExpression(PsiExpression expression) {
+ buffer.append(expression.getText());
+ }
+
+ @Override
+ public void visitNewExpression(PsiNewExpression expression) {
+ PsiArrayInitializerExpression arrayInitializer = expression.getArrayInitializer();
+ if (arrayInitializer == null) {
+ super.visitNewExpression(expression);
+ }
+ else {
+ buffer.append(")");
+ }
+ }
+
+ });
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java
index f1afadd..536c2cc 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java
@@ -205,6 +205,7 @@
public void testIDEADEV40479() throws Exception { doTest(); }
public void testMultilineReturn() throws Exception { doTest(); }
+ public void testMultilineCall() throws Exception { doTest(); }
public void testIDEADEV13019() throws Exception {
doTestBracesNextLineStyle();
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 0a31d5e..6690708 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
@@ -1464,5 +1464,34 @@
assert !lookup
}
+ public void "test template prefix is better than middle matches"() {
+ myFixture.configureByText "a.java", """
+class Cls {
+ void foo() {
+ <caret>
+ }
+ void mySout() {}
+}
+"""
+ type('sout')
+ myFixture.assertPreferredCompletionItems 0, 'sout', 'mySout'
+ }
+
+ public void "test single overriding getter"() {
+ myFixture.configureByText "a.java", """
+public class Foo {
+ public int getField() {}
+}
+
+class X extends Foo {
+ int field;
+
+ <caret>
+}
+"""
+ type 'getf'
+ assert myFixture.lookupElementStrings == ['public int getField']
+ }
+
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.groovy
index fedb91c..5f92714 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.groovy
@@ -267,6 +267,27 @@
myFixture.assertPreferredCompletionItems 0, 'see', 'see bar.Bar', 'see foo.Foo'
}
+ public void testShortenMethodParameterTypes() {
+ CodeStyleSettingsManager.getSettings(getProject()).USE_FQ_CLASS_NAMES_IN_JAVADOC = false
+ try {
+ myFixture.addClass("package foo; public class Foo {}")
+ myFixture.configureByText "a.java", '''
+import foo.*;
+
+/**
+ * {@link #go<caret>
+ */
+class Goo { void goo(Foo foo {} }
+'''
+ myFixture.completeBasic()
+ assert myFixture.editor.document.text.contains('@link #goo(Foo)')
+ }
+ finally {
+ CodeStyleSettingsManager.getSettings(getProject()).USE_FQ_CLASS_NAMES_IN_JAVADOC = true
+ }
+
+ }
+
public void testCustomReferenceProvider() throws Exception {
PsiReferenceRegistrarImpl registrar =
(PsiReferenceRegistrarImpl) ReferenceProvidersRegistry.getInstance().getRegistrar(StdLanguages.JAVA);
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 64f2f02c..05e8feb 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy
@@ -36,6 +36,10 @@
checkPreferredItems(0, "return", "register");
}
+ public void testDelegatingConstructorCall() {
+ checkPreferredItems 0, 'element', 'equals'
+ }
+
public void testPreferAnnotationMethods() throws Throwable {
checkPreferredItems(0, "name", "value", "Foo", "Anno");
}
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 0363b0f..968d078 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java
@@ -16,7 +16,7 @@
package com.intellij.codeInsight.daemon;
import com.intellij.analysis.PackagesScopesProvider;
-import com.intellij.application.options.colors.ColorAndFontOptions;
+import com.intellij.application.options.colors.ScopeAttributesUtil;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.editor.colors.EditorColorsManager;
@@ -188,11 +188,11 @@
EditorColorsScheme scheme = (EditorColorsScheme)manager.getGlobalScheme().clone();
manager.addColorsScheme(scheme);
EditorColorsManager.getInstance().setGlobalScheme(scheme);
- TextAttributesKey xKey = ColorAndFontOptions.getScopeTextAttributeKey(xScope.getName());
+ TextAttributesKey xKey = ScopeAttributesUtil.getScopeTextAttributeKey(xScope.getName());
TextAttributes xAttributes = new TextAttributes(Color.cyan, Color.darkGray, Color.blue, EffectType.BOXED, Font.ITALIC);
scheme.setAttributes(xKey, xAttributes);
- TextAttributesKey utilKey = ColorAndFontOptions.getScopeTextAttributeKey(utilScope.getName());
+ TextAttributesKey utilKey = ScopeAttributesUtil.getScopeTextAttributeKey(utilScope.getName());
TextAttributes utilAttributes = new TextAttributes(Color.gray, Color.magenta, Color.orange, EffectType.STRIKEOUT, Font.BOLD);
scheme.setAttributes(utilKey, utilAttributes);
@@ -215,16 +215,16 @@
EditorColorsScheme scheme = (EditorColorsScheme)manager.getGlobalScheme().clone();
manager.addColorsScheme(scheme);
EditorColorsManager.getInstance().setGlobalScheme(scheme);
- TextAttributesKey xKey = ColorAndFontOptions.getScopeTextAttributeKey(xScope.getName());
+ TextAttributesKey xKey = ScopeAttributesUtil.getScopeTextAttributeKey(xScope.getName());
TextAttributes xAttributes = new TextAttributes(Color.cyan, Color.darkGray, Color.blue, null, Font.ITALIC);
scheme.setAttributes(xKey, xAttributes);
- TextAttributesKey utilKey = ColorAndFontOptions.getScopeTextAttributeKey(utilScope.getName());
+ TextAttributesKey utilKey = ScopeAttributesUtil.getScopeTextAttributeKey(utilScope.getName());
TextAttributes utilAttributes = new TextAttributes(Color.gray, Color.magenta, Color.orange, EffectType.STRIKEOUT, Font.BOLD);
scheme.setAttributes(utilKey, utilAttributes);
NamedScope projectScope = PackagesScopesProvider.getInstance(myProject).getProjectProductionScope();
- TextAttributesKey projectKey = ColorAndFontOptions.getScopeTextAttributeKey(projectScope.getName());
+ TextAttributesKey projectKey = ScopeAttributesUtil.getScopeTextAttributeKey(projectScope.getName());
TextAttributes projectAttributes = new TextAttributes(null, null, Color.blue, EffectType.BOXED, Font.ITALIC);
scheme.setAttributes(projectKey, projectAttributes);
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 a0c0ffa..0333f9e 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
@@ -314,6 +314,7 @@
public void testBoxingSpecific() { doTest5(false); }
public void testIDEA67843() { doTest5(false); }
public void testAmbiguousTypeParamVsConcrete() { doTest5(false); }
+ public void testRawAssignments() throws Exception { 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/lambda/MethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
index 9eecd70..064b2c3 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
@@ -83,6 +83,10 @@
doTest();
}
+ public void testIDEA112323() throws Exception {
+ doTest();
+ }
+
private void doTest() {
doTest(false);
}
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 12ed060..223e911 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy
@@ -640,4 +640,18 @@
"""
}
+ public void "test stop at SELECTION when invoked surround template by tab"() {
+ myFixture.configureByText "a.txt", "<caret>"
+
+ final TemplateManager manager = TemplateManager.getInstance(getProject());
+ final Template template = manager.createTemplate("xxx", "user", 'foo $ARG$ bar $END$ goo $SELECTION$ after');
+ template.addVariable("ARG", "", "", true);
+
+ manager.startTemplate(editor, template);
+ myFixture.type('arg')
+ state.nextTab()
+ assert !state
+ checkResultByText 'foo arg bar goo <caret> after';
+ }
+
}
diff --git a/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java b/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
index 95e80d2..72e9c2a 100644
--- a/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
+++ b/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
@@ -42,6 +42,6 @@
public void testMatcher1() throws Exception {checkTree("ico");}
public void testMatcher2() throws Exception {checkTree("ico");}
- @Bombed(user = "peter", month = Calendar.AUGUST, day = 20)
+ @Bombed(user = "peter", month = Calendar.SEPTEMBER, day = 20)
public void testAnonymousMatcher2() throws Exception {checkTree("ico");}
}
diff --git a/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/FileParserTest.java b/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/FileParserTest.java
index 52766f5..8b39692 100644
--- a/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/FileParserTest.java
+++ b/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/FileParserTest.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.
@@ -19,7 +19,6 @@
import com.intellij.lang.java.parser.JavaParser;
import com.intellij.lang.java.parser.JavaParsingTestCase;
-
public class FileParserTest extends JavaParsingTestCase {
public FileParserTest() {
super("parser-partial/files");
@@ -41,6 +40,10 @@
public void testUnclosedImport2() { doParserTest("import java.awt."); }
public void testUnclosedImport3() { doParserTest("import static a"); }
+ public void testExtraSemicolons() { doParserTest("package p;;\n" +
+ "import a;;\n" +
+ "class C{};"); }
+
public void testFileWithClass() { doParserTest("package a;\n" +
"import b;\n" +
"public class C { }\n" +
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
index 88537b7..b566465 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
@@ -591,6 +591,10 @@
doTest();
}
+ public void testExpression() throws Exception {
+ doTest();
+ }
+
private void doTestDisabledParam() throws PrepareFailedException {
final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
settings.ELSE_ON_NEW_LINE = true;
diff --git a/java/jdkAnnotations/java/lang/annotations.xml b/java/jdkAnnotations/java/lang/annotations.xml
index d5cc0c4..8863fc9 100644
--- a/java/jdkAnnotations/java/lang/annotations.xml
+++ b/java/jdkAnnotations/java/lang/annotations.xml
@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<root>
+ <item name='java.lang.Boolean boolean getBoolean(java.lang.String) 0'>
+ <annotation name='org.jetbrains.annotations.NonNls'/>
+ </item>
<item name="java.lang.CharSequence java.lang.String toString()">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
diff --git a/java/jdkAnnotations/java/util/annotations.xml b/java/jdkAnnotations/java/util/annotations.xml
index 47962ab..58ea647 100644
--- a/java/jdkAnnotations/java/util/annotations.xml
+++ b/java/jdkAnnotations/java/util/annotations.xml
@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<root>
+ <item name='java.util.AbstractCollection T[] toArray(T[]) 0'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
<item name="java.util.ArrayList ArrayList(java.util.Collection<? extends E>) 0">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
@@ -845,6 +848,30 @@
<item name="java.util.NavigableSet java.util.NavigableSet<E> tailSet(E, boolean)">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
+ <item name='java.util.Set T[] toArray(T[])'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
+ <item name='java.util.Set T[] toArray(T[]) 0'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
+ <item name='java.util.Set boolean addAll(java.util.Collection<? extends E>) 0'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
+ <item name='java.util.Set boolean containsAll(java.util.Collection<?>) 0'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
+ <item name='java.util.Set boolean removeAll(java.util.Collection<?>) 0'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
+ <item name='java.util.Set boolean retainAll(java.util.Collection<?>) 0'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
+ <item name='java.util.Set java.lang.Object[] toArray()'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
+ <item name='java.util.Set java.util.Iterator<E> iterator()'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
<item name="java.util.SortedMap java.util.Comparator<? super K> comparator()">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
diff --git a/java/jdkAnnotations/java/util/concurrent/annotations.xml b/java/jdkAnnotations/java/util/concurrent/annotations.xml
index 661e32a..0083087 100644
--- a/java/jdkAnnotations/java/util/concurrent/annotations.xml
+++ b/java/jdkAnnotations/java/util/concurrent/annotations.xml
@@ -3,6 +3,9 @@
<item name="java.util.concurrent.BlockingQueue E poll(long, java.util.concurrent.TimeUnit) 1">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
+ <item name='java.util.concurrent.BlockingQueue boolean offer(E) 0'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
<item name="java.util.concurrent.BlockingQueue boolean offer(E, long, java.util.concurrent.TimeUnit) 2">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
@@ -201,6 +204,9 @@
<item name="java.util.concurrent.FutureTask V get(long, java.util.concurrent.TimeUnit) 1">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
+ <item name='java.util.concurrent.LinkedBlockingQueue boolean offer(E) 0'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
<item name="java.util.concurrent.ScheduledExecutorService java.util.concurrent.ScheduledFuture<?> schedule(java.lang.Runnable, long, java.util.concurrent.TimeUnit)">
<annotation name="org.jetbrains.annotations.NotNull" />
</item>
diff --git a/java/manifest/manifest.iml b/java/manifest/manifest.iml
new file mode 100644
index 0000000..1c394dd
--- /dev/null
+++ b/java/manifest/manifest.iml
@@ -0,0 +1,22 @@
+<?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$/test" isTestSource="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="util" />
+ <orderEntry type="module" module-name="core-api" />
+ <orderEntry type="module" module-name="analysis-api" />
+ <orderEntry type="module" module-name="platform-api" />
+ <orderEntry type="module" module-name="lang-api" />
+ <orderEntry type="module" module-name="core-impl" />
+ <orderEntry type="module" module-name="java-psi-api" />
+ <orderEntry type="module" module-name="java-impl" />
+ <orderEntry type="module" module-name="testFramework-java" scope="TEST" />
+ </component>
+</module>
+
diff --git a/java/manifest/src/inspectionDescriptions/MissingFinalNewline.html b/java/manifest/src/inspectionDescriptions/MissingFinalNewline.html
new file mode 100644
index 0000000..c02bc3b
--- /dev/null
+++ b/java/manifest/src/inspectionDescriptions/MissingFinalNewline.html
@@ -0,0 +1,30 @@
+<!--
+ ~ Copyright (c) 2007-2009, Osmorc Development Team
+ ~ All rights reserved.
+ ~
+ ~ Redistribution and use in source and binary forms, with or without modification,
+ ~ are permitted provided that the following conditions are met:
+ ~ * Redistributions of source code must retain the above copyright notice, this list
+ ~ of conditions and the following disclaimer.
+ ~ * Redistributions in binary form must reproduce the above copyright notice, this
+ ~ list of conditions and the following disclaimer in the documentation and/or other
+ ~ materials provided with the distribution.
+ ~ * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ ~ used to endorse or promote products derived from this software without specific
+ ~ prior written permission.
+ ~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ ~ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ ~ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ ~ THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ~ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ ~ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ~ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ ~ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ ~ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ -->
+
+<html>
+<body>
+ <p>Checks whether a manifest file ends with a final newline (as required by the JAR file specification).</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/java/manifest/src/inspectionDescriptions/MisspelledHeader.html b/java/manifest/src/inspectionDescriptions/MisspelledHeader.html
new file mode 100644
index 0000000..325bcb0
--- /dev/null
+++ b/java/manifest/src/inspectionDescriptions/MisspelledHeader.html
@@ -0,0 +1,30 @@
+<!--
+ ~ Copyright (c) 2007-2009, Osmorc Development Team
+ ~ All rights reserved.
+ ~
+ ~ Redistribution and use in source and binary forms, with or without modification,
+ ~ are permitted provided that the following conditions are met:
+ ~ * Redistributions of source code must retain the above copyright notice, this list
+ ~ of conditions and the following disclaimer.
+ ~ * Redistributions in binary form must reproduce the above copyright notice, this
+ ~ list of conditions and the following disclaimer in the documentation and/or other
+ ~ materials provided with the distribution.
+ ~ * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ ~ used to endorse or promote products derived from this software without specific
+ ~ prior written permission.
+ ~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ ~ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ ~ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ ~ THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ~ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ ~ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ~ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ ~ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ ~ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ -->
+
+<html>
+<body>
+ <p>Reports any unknown and probably misspelled header names and provides possible variants.</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/ManifestBundle.java b/java/manifest/src/org/jetbrains/lang/manifest/ManifestBundle.java
new file mode 100644
index 0000000..4d5fe2c
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/ManifestBundle.java
@@ -0,0 +1,33 @@
+/*
+ * 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 org.jetbrains.lang.manifest;
+
+import com.intellij.AbstractBundle;
+import org.jetbrains.annotations.PropertyKey;
+
+public class ManifestBundle extends AbstractBundle {
+ public static final String PATH_TO_BUNDLE = "org.jetbrains.lang.manifest.ManifestBundle";
+
+ private static final ManifestBundle BUNDLE = new ManifestBundle();
+
+ private ManifestBundle() {
+ super(PATH_TO_BUNDLE);
+ }
+
+ public static String message(@PropertyKey(resourceBundle = PATH_TO_BUNDLE) String key, Object... params) {
+ return BUNDLE.getMessage(key, params);
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/ManifestBundle.properties b/java/manifest/src/org/jetbrains/lang/manifest/ManifestBundle.properties
new file mode 100644
index 0000000..b216895
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/ManifestBundle.properties
@@ -0,0 +1,14 @@
+manifest.unexpected.token=Unexpected token
+manifest.colon.expected=':' expected
+manifest.whitespace.expected=Whitespace expected
+manifest.header.expected=Header expected
+
+header.reference.invalid=Invalid reference
+header.reference.unknown=Cannot resolve
+header.main.class.invalid=Invalid main class
+
+inspection.group=Manifest
+inspection.newline.message=Manifest file doesn't end with a final newline
+inspection.newline.fix=Add newline
+inspection.header.message=Header name is unknown or spelled incorrectly
+inspection.header.fix=Change to ''{0}''
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/ManifestFileType.java b/java/manifest/src/org/jetbrains/lang/manifest/ManifestFileType.java
new file mode 100644
index 0000000..553d673
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/ManifestFileType.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class ManifestFileType extends LanguageFileType {
+ public ManifestFileType() {
+ super(ManifestLanguage.INSTANCE);
+ }
+
+ @NotNull
+ @NonNls
+ @Override
+ public String getName() {
+ return "Manifest";
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Manifest";
+ }
+
+ @NotNull
+ @NonNls
+ @Override
+ public String getDefaultExtension() {
+ return "MF";
+ }
+
+ @Nullable
+ @Override
+ public Icon getIcon() {
+ return AllIcons.FileTypes.Manifest;
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/ManifestFileTypeFactory.java b/java/manifest/src/org/jetbrains/lang/manifest/ManifestFileTypeFactory.java
new file mode 100644
index 0000000..e6e31cc
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/ManifestFileTypeFactory.java
@@ -0,0 +1,33 @@
+/*
+ * 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 org.jetbrains.lang.manifest;
+
+import com.intellij.openapi.fileTypes.FileTypeConsumer;
+import com.intellij.openapi.fileTypes.FileTypeFactory;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public class ManifestFileTypeFactory extends FileTypeFactory {
+ public final static LanguageFileType MANIFEST = new ManifestFileType();
+
+ @Override
+ public void createFileTypes(@NotNull FileTypeConsumer consumer) {
+ consumer.consume(MANIFEST, "MF");
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/ManifestLanguage.java b/java/manifest/src/org/jetbrains/lang/manifest/ManifestLanguage.java
new file mode 100644
index 0000000..88204be
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/ManifestLanguage.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest;
+
+import com.intellij.lang.Language;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class ManifestLanguage extends Language {
+ public static final ManifestLanguage INSTANCE = new ManifestLanguage();
+
+ public ManifestLanguage() {
+ super("Manifest");
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/completion/ManifestCompletionContributor.java b/java/manifest/src/org/jetbrains/lang/manifest/completion/ManifestCompletionContributor.java
new file mode 100644
index 0000000..554c25b
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/completion/ManifestCompletionContributor.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.completion;
+
+import com.intellij.codeInsight.completion.*;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.openapi.editor.EditorModificationUtil;
+import com.intellij.patterns.PlatformPatterns;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.lang.manifest.ManifestLanguage;
+import org.jetbrains.lang.manifest.header.HeaderParserRepository;
+import org.jetbrains.lang.manifest.psi.ManifestTokenType;
+
+/**
+ * Completion contributor which adds the name of all known headers to the autocomplete list.
+ *
+ * @author <a href="mailto:janthomae@janthomae.de">Jan Thomä</a>
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class ManifestCompletionContributor extends CompletionContributor {
+ public ManifestCompletionContributor(@NotNull final HeaderParserRepository repository) {
+ extend(CompletionType.BASIC,
+ PlatformPatterns.psiElement(ManifestTokenType.HEADER_NAME).withLanguage(ManifestLanguage.INSTANCE),
+ new CompletionProvider<CompletionParameters>() {
+ @Override
+ public void addCompletions(@NotNull CompletionParameters parameters,
+ ProcessingContext context,
+ @NotNull CompletionResultSet resultSet) {
+ for (String header : repository.getAllHeaderNames()) {
+ resultSet.addElement(LookupElementBuilder.create(header).withInsertHandler(HEADER_INSERT_HANDLER));
+ }
+ }
+ }
+ );
+ }
+
+ private static final InsertHandler<LookupElement> HEADER_INSERT_HANDLER = new InsertHandler<LookupElement>() {
+ @Override
+ public void handleInsert(InsertionContext context, LookupElement item) {
+ context.setAddCompletionChar(false);
+ EditorModificationUtil.insertStringAtCaret(context.getEditor(), ": ");
+ context.commitDocument();
+ }
+ };
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/header/HeaderNameMatch.java b/java/manifest/src/org/jetbrains/lang/manifest/header/HeaderNameMatch.java
new file mode 100644
index 0000000..8ab3669
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/header/HeaderNameMatch.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.header;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * A match describes how good a header known to a particular header provider matches a given header.
+ * The name of the given header may contain typos and so there may be no perfect match. A perfect match will
+ * have a Levenshtein distance of 0. Worse matches will have greater Levenshtein distances.
+ *
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class HeaderNameMatch implements Comparable<HeaderNameMatch> {
+ private final int myDistance;
+ private final String myHeaderName;
+
+ public HeaderNameMatch(int distance, @NotNull String headerName) {
+ myDistance = distance;
+ myHeaderName = headerName;
+ }
+
+ public int getDistance() {
+ return myDistance;
+ }
+
+ public String getHeaderName() {
+ return myHeaderName;
+ }
+
+ /**
+ * Matches are compared based on their distance.
+ */
+ @Override
+ public int compareTo(@NotNull HeaderNameMatch o) {
+ return getDistance() - o.getDistance();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ HeaderNameMatch that = (HeaderNameMatch)o;
+
+ return myDistance == that.myDistance && myHeaderName.equals(that.myHeaderName);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = myDistance;
+ result = 31 * result + myHeaderName.hashCode();
+ return result;
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/header/HeaderParser.java b/java/manifest/src/org/jetbrains/lang/manifest/header/HeaderParser.java
new file mode 100644
index 0000000..31c3faf
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/header/HeaderParser.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.header;
+
+import com.intellij.lang.PsiBuilder;
+import com.intellij.lang.annotation.AnnotationHolder;
+import com.intellij.psi.PsiReference;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.lang.manifest.psi.Header;
+import org.jetbrains.lang.manifest.psi.HeaderValuePart;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public interface HeaderParser {
+ /**
+ * Parses a header starting from a first token after semicolon and space.
+ */
+ void parse(@NotNull PsiBuilder builder);
+
+ /**
+ * Annotates the header with errors or any other useful information.
+ * Should return true if the element was annotated with errors.
+ */
+ boolean annotate(@NotNull Header header, @NotNull AnnotationHolder holder);
+
+ /**
+ * Returns the raw data of the header converted into some domain specific value (e.g. Version or VersionRange).
+ */
+ @Nullable
+ Object getConvertedValue(@NotNull Header header);
+
+ /**
+ * Returns references from a given header value, or empty array if none/not applicable.
+ */
+ @NotNull
+ PsiReference[] getReferences(@NotNull HeaderValuePart headerValuePart);
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/header/HeaderParserProvider.java b/java/manifest/src/org/jetbrains/lang/manifest/header/HeaderParserProvider.java
new file mode 100644
index 0000000..d101349
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/header/HeaderParserProvider.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.header;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Map;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public interface HeaderParserProvider {
+ ExtensionPointName<HeaderParserProvider> EP_NAME = ExtensionPointName.create("com.intellij.manifest.parser.provider");
+
+ @NotNull
+ Map<String, HeaderParser> getHeaderParsers();
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/header/HeaderParserRepository.java b/java/manifest/src/org/jetbrains/lang/manifest/header/HeaderParserRepository.java
new file mode 100644
index 0000000..27b80df
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/header/HeaderParserRepository.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.header;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.util.NotNullLazyValue;
+import com.intellij.openapi.util.text.LevenshteinDistance;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.lang.manifest.psi.Header;
+import org.jetbrains.lang.manifest.psi.HeaderValuePart;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class HeaderParserRepository {
+ public static HeaderParserRepository getInstance() {
+ return ServiceManager.getService(HeaderParserRepository.class);
+ }
+
+ private final NotNullLazyValue<Map<String, HeaderParser>> myParsers = new NotNullLazyValue<Map<String, HeaderParser>>() {
+ @NotNull
+ @Override
+ protected Map<String, HeaderParser> compute() {
+ Map<String, HeaderParser> map = ContainerUtil.newHashMap();
+ for (HeaderParserProvider provider : Extensions.getExtensions(HeaderParserProvider.EP_NAME)) {
+ map.putAll(provider.getHeaderParsers());
+ }
+ return map;
+ }
+ };
+
+ @Nullable
+ public HeaderParser getHeaderParser(@Nullable String headerName) {
+ return myParsers.getValue().get(headerName);
+ }
+
+ @NotNull
+ public Collection<HeaderNameMatch> getMatches(@NotNull String headerName) {
+ HeaderParser parser = myParsers.getValue().get(headerName);
+ if (parser != null) {
+ return ContainerUtil.emptyList();
+ }
+
+ LevenshteinDistance distance = new LevenshteinDistance();
+ Set<HeaderNameMatch> result = new TreeSet<HeaderNameMatch>();
+ for (Map.Entry<String, HeaderParser> entry : myParsers.getValue().entrySet()) {
+ String otherName = entry.getKey();
+ int dist = distance.calculateMetrics(headerName, otherName);
+ result.add(new HeaderNameMatch(dist, otherName));
+ }
+ return result;
+ }
+
+ @NotNull
+ public Set<String> getAllHeaderNames() {
+ return myParsers.getValue().keySet();
+ }
+
+ @Nullable
+ public Object getConvertedValue(@NotNull Header header) {
+ HeaderParser parser = getHeaderParser(header.getName());
+ return parser != null ? parser.getConvertedValue(header) : null;
+ }
+
+ @NotNull
+ public PsiReference[] getReferences(@NotNull HeaderValuePart headerValuePart) {
+ Header header = PsiTreeUtil.getParentOfType(headerValuePart, Header.class);
+ if (header != null) {
+ HeaderParser parser = getHeaderParser(header.getName());
+ if (parser != null) {
+ return parser.getReferences(headerValuePart);
+ }
+ }
+
+ return PsiReference.EMPTY_ARRAY;
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/header/impl/ClassReferenceParser.java b/java/manifest/src/org/jetbrains/lang/manifest/header/impl/ClassReferenceParser.java
new file mode 100644
index 0000000..3a87727
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/header/impl/ClassReferenceParser.java
@@ -0,0 +1,97 @@
+/*
+ * 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 org.jetbrains.lang.manifest.header.impl;
+
+import com.intellij.lang.annotation.AnnotationHolder;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceProvider;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiMethodUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.lang.manifest.ManifestBundle;
+import org.jetbrains.lang.manifest.header.HeaderParser;
+import org.jetbrains.lang.manifest.psi.Header;
+import org.jetbrains.lang.manifest.psi.HeaderValue;
+import org.jetbrains.lang.manifest.psi.HeaderValuePart;
+
+public class ClassReferenceParser extends StandardHeaderParser {
+ public static final HeaderParser INSTANCE = new ClassReferenceParser();
+
+ @NotNull
+ @Override
+ public PsiReference[] getReferences(@NotNull HeaderValuePart headerValuePart) {
+ final Module module = ModuleUtilCore.findModuleForPsiElement(headerValuePart);
+ JavaClassReferenceProvider provider;
+ if (module != null) {
+ provider = new JavaClassReferenceProvider() {
+ @Override
+ public GlobalSearchScope getScope(Project project) {
+ return GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module);
+ }
+ };
+ }
+ else {
+ provider = new JavaClassReferenceProvider();
+ }
+ return provider.getReferencesByElement(headerValuePart);
+ }
+
+ @Override
+ public boolean annotate(@NotNull Header header, @NotNull AnnotationHolder holder) {
+ HeaderValue value = header.getHeaderValue();
+ if (!(value instanceof HeaderValuePart)) return false;
+
+ PsiReference[] references = value.getReferences();
+ if (references.length == 0) {
+ holder.createErrorAnnotation(((HeaderValuePart)value).getHighlightingRange(), ManifestBundle.message("header.reference.invalid"));
+ return true;
+ }
+
+ for (int i = 0; i < references.length; i++) {
+ PsiReference reference = references[i];
+ PsiElement element = reference.resolve();
+ if (element == null) {
+ TextRange range = reference.getRangeInElement().shiftRight(value.getTextOffset());
+ holder.createErrorAnnotation(range, ManifestBundle.message("header.reference.unknown"));
+ return true;
+ }
+
+ if (i == references.length - 1) {
+ if (checkClass(reference, element, holder)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ protected boolean checkClass(@NotNull PsiReference reference, @NotNull PsiElement element, @NotNull AnnotationHolder holder) {
+ if (element instanceof PsiClass && PsiMethodUtil.hasMainMethod((PsiClass)element)) {
+ return false;
+ }
+
+ TextRange range = reference.getRangeInElement().shiftRight(reference.getElement().getTextOffset());
+ holder.createErrorAnnotation(range, ManifestBundle.message("header.main.class.invalid"));
+ return true;
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/header/impl/StandardHeaderParser.java b/java/manifest/src/org/jetbrains/lang/manifest/header/impl/StandardHeaderParser.java
new file mode 100644
index 0000000..7aeb792
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/header/impl/StandardHeaderParser.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.header.impl;
+
+import com.intellij.lang.PsiBuilder;
+import com.intellij.lang.annotation.AnnotationHolder;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.lang.manifest.header.HeaderParser;
+import org.jetbrains.lang.manifest.parser.ManifestParser;
+import org.jetbrains.lang.manifest.psi.*;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class StandardHeaderParser implements HeaderParser {
+ public static final HeaderParser INSTANCE = new StandardHeaderParser();
+
+ @Override
+ public void parse(@NotNull PsiBuilder builder) {
+ PsiBuilder.Marker marker = builder.mark();
+ while (!builder.eof() && !ManifestParser.HEADER_END_TOKENS.contains(builder.getTokenType())) {
+ IElementType lastToken = builder.getTokenType();
+ builder.advanceLexer();
+ if (lastToken == ManifestTokenType.NEWLINE && builder.getTokenType() != ManifestTokenType.SIGNIFICANT_SPACE) {
+ break;
+ }
+ }
+ marker.done(ManifestElementType.HEADER_VALUE_PART);
+ }
+
+ @Override
+ public boolean annotate(@NotNull Header header, @NotNull AnnotationHolder holder) {
+ return false;
+ }
+
+ @Nullable
+ @Override
+ public Object getConvertedValue(@NotNull Header header) {
+ HeaderValue value = header.getHeaderValue();
+ return value != null ? value.getUnwrappedText() : null;
+ }
+
+ @NotNull
+ @Override
+ public PsiReference[] getReferences(@NotNull HeaderValuePart headerValuePart) {
+ return PsiReference.EMPTY_ARRAY;
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/header/impl/StandardManifestHeaderParsers.java b/java/manifest/src/org/jetbrains/lang/manifest/header/impl/StandardManifestHeaderParsers.java
new file mode 100644
index 0000000..c6adcbb
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/header/impl/StandardManifestHeaderParsers.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.header.impl;
+
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.lang.manifest.header.HeaderParser;
+import org.jetbrains.lang.manifest.header.HeaderParserProvider;
+
+import java.util.Map;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class StandardManifestHeaderParsers implements HeaderParserProvider {
+ private final Map<String, HeaderParser> myParsers;
+
+ public StandardManifestHeaderParsers() {
+ myParsers = ContainerUtil.newHashMap();
+ myParsers.put("Manifest-Version", StandardHeaderParser.INSTANCE);
+ myParsers.put("Created-By", StandardHeaderParser.INSTANCE);
+ myParsers.put("Signature-Version", StandardHeaderParser.INSTANCE);
+ myParsers.put("Class-Path", StandardHeaderParser.INSTANCE);
+ myParsers.put("Main-Class", ClassReferenceParser.INSTANCE);
+ myParsers.put("Implementation-Title", StandardHeaderParser.INSTANCE);
+ myParsers.put("Implementation-Version", StandardHeaderParser.INSTANCE);
+ myParsers.put("Implementation-Vendor", StandardHeaderParser.INSTANCE);
+ myParsers.put("Implementation-Vendor-Id", StandardHeaderParser.INSTANCE);
+ myParsers.put("Implementation-URL", StandardHeaderParser.INSTANCE);
+ myParsers.put("Specification-Title", StandardHeaderParser.INSTANCE);
+ myParsers.put("Specification-Version", StandardHeaderParser.INSTANCE);
+ myParsers.put("Specification-Vendor", StandardHeaderParser.INSTANCE);
+ myParsers.put("Sealed", StandardHeaderParser.INSTANCE);
+ myParsers.put("Name", StandardHeaderParser.INSTANCE);
+ myParsers.put("Content-Type", StandardHeaderParser.INSTANCE);
+ myParsers.put("Java-Bean", StandardHeaderParser.INSTANCE);
+ myParsers.put("MD5-Digest", StandardHeaderParser.INSTANCE);
+ myParsers.put("SHA-Digest", StandardHeaderParser.INSTANCE);
+ myParsers.put("Magic", StandardHeaderParser.INSTANCE);
+ }
+
+ @NotNull
+ @Override
+ public Map<String, HeaderParser> getHeaderParsers() {
+ return myParsers;
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/highlighting/HeaderAnnotator.java b/java/manifest/src/org/jetbrains/lang/manifest/highlighting/HeaderAnnotator.java
new file mode 100644
index 0000000..bf2c43e
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/highlighting/HeaderAnnotator.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.highlighting;
+
+import com.intellij.lang.annotation.AnnotationHolder;
+import com.intellij.lang.annotation.Annotator;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.lang.manifest.header.HeaderParser;
+import org.jetbrains.lang.manifest.header.HeaderParserRepository;
+import org.jetbrains.lang.manifest.psi.Header;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class HeaderAnnotator implements Annotator {
+ private final HeaderParserRepository myRepository;
+
+ public HeaderAnnotator(@NotNull HeaderParserRepository repository) {
+ myRepository = repository;
+ }
+
+ @Override
+ public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder) {
+ if (psiElement instanceof Header) {
+ Header header = (Header)psiElement;
+ HeaderParser headerParser = myRepository.getHeaderParser(header.getName());
+ if (headerParser != null) {
+ headerParser.annotate(header, holder);
+ }
+ }
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/highlighting/ManifestColorsAndFonts.java b/java/manifest/src/org/jetbrains/lang/manifest/highlighting/ManifestColorsAndFonts.java
new file mode 100644
index 0000000..453235d
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/highlighting/ManifestColorsAndFonts.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.highlighting;
+
+import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class ManifestColorsAndFonts {
+ public static final TextAttributesKey HEADER_NAME_KEY =
+ TextAttributesKey.createTextAttributesKey("manifest.header.name", DefaultLanguageHighlighterColors.KEYWORD);
+ public static final TextAttributesKey HEADER_ASSIGNMENT_KEY =
+ TextAttributesKey.createTextAttributesKey("manifest.header.assignment", DefaultLanguageHighlighterColors.OPERATION_SIGN);
+ public static final TextAttributesKey HEADER_VALUE_KEY =
+ TextAttributesKey.createTextAttributesKey("manifest.header.value", DefaultLanguageHighlighterColors.IDENTIFIER);
+
+ private ManifestColorsAndFonts() { }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/highlighting/ManifestSyntaxHighlighterFactory.java b/java/manifest/src/org/jetbrains/lang/manifest/highlighting/ManifestSyntaxHighlighterFactory.java
new file mode 100644
index 0000000..765eac5
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/highlighting/ManifestSyntaxHighlighterFactory.java
@@ -0,0 +1,62 @@
+/*
+ * 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 org.jetbrains.lang.manifest.highlighting;
+
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.fileTypes.SyntaxHighlighter;
+import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
+import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.lang.manifest.parser.ManifestLexer;
+import org.jetbrains.lang.manifest.psi.ManifestTokenType;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ManifestSyntaxHighlighterFactory extends SyntaxHighlighterFactory {
+ public static final SyntaxHighlighter HIGHLIGHTER = new SyntaxHighlighterBase() {
+ private final Map<IElementType, TextAttributesKey> myAttributes;
+ {
+ myAttributes = new HashMap<IElementType, TextAttributesKey>();
+ myAttributes.put(ManifestTokenType.HEADER_NAME, ManifestColorsAndFonts.HEADER_NAME_KEY);
+ myAttributes.put(ManifestTokenType.COLON, ManifestColorsAndFonts.HEADER_ASSIGNMENT_KEY);
+ myAttributes.put(ManifestTokenType.HEADER_VALUE_PART, ManifestColorsAndFonts.HEADER_VALUE_KEY);
+ }
+
+ @NotNull
+ @Override
+ public Lexer getHighlightingLexer() {
+ return new ManifestLexer();
+ }
+
+ @NotNull
+ @Override
+ public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
+ return pack(myAttributes.get(tokenType));
+ }
+ };
+
+ @NotNull
+ @Override
+ public SyntaxHighlighter getSyntaxHighlighter(@Nullable Project project, @Nullable VirtualFile virtualFile) {
+ return HIGHLIGHTER;
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/highlighting/MissingFinalNewlineInspection.java b/java/manifest/src/org/jetbrains/lang/manifest/highlighting/MissingFinalNewlineInspection.java
new file mode 100644
index 0000000..7404b27
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/highlighting/MissingFinalNewlineInspection.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.highlighting;
+
+import com.intellij.codeInspection.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.lang.manifest.ManifestBundle;
+import org.jetbrains.lang.manifest.psi.Header;
+import org.jetbrains.lang.manifest.psi.ManifestFile;
+import org.jetbrains.lang.manifest.psi.ManifestTokenType;
+import org.jetbrains.lang.manifest.psi.Section;
+
+import java.util.List;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class MissingFinalNewlineInspection extends LocalInspectionTool {
+ @Override
+ public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
+ if (file instanceof ManifestFile) {
+ String text = file.getText();
+ if (text != null && text.length() > 0 && !StringUtil.endsWith(text, "\n")) {
+ List<Section> sections = ((ManifestFile)file).getSections();
+ assert sections.size() > 0 : text;
+ Section section = sections.get(sections.size() - 1);
+ ProblemDescriptor descriptor = manager.createProblemDescriptor(
+ section.getLastChild(), ManifestBundle.message("inspection.newline.message"),
+ new AddNewlineQuickFix(section), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly
+ );
+ return new ProblemDescriptor[]{descriptor};
+ }
+ }
+
+ return null;
+ }
+
+ private static class AddNewlineQuickFix implements LocalQuickFix {
+ private final Section mySection;
+
+ private AddNewlineQuickFix(Section section) {
+ mySection = section;
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return ManifestBundle.message("inspection.newline.fix");
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return ManifestBundle.message("inspection.group");
+ }
+
+ @Override
+ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+ PsiElement lastChild = mySection.getLastChild();
+ if (lastChild instanceof Header) {
+ lastChild.getNode().addLeaf(ManifestTokenType.NEWLINE, "\n", null);
+ }
+ }
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/highlighting/MisspelledHeaderInspection.java b/java/manifest/src/org/jetbrains/lang/manifest/highlighting/MisspelledHeaderInspection.java
new file mode 100644
index 0000000..75f4176
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/highlighting/MisspelledHeaderInspection.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.highlighting;
+
+import com.intellij.codeInspection.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.lang.manifest.ManifestBundle;
+import org.jetbrains.lang.manifest.header.HeaderNameMatch;
+import org.jetbrains.lang.manifest.header.HeaderParserRepository;
+import org.jetbrains.lang.manifest.psi.Header;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class MisspelledHeaderInspection extends LocalInspectionTool {
+ private static final int MAX_SUGGESTIONS = 10;
+
+ private HeaderParserRepository myRepository;
+
+ public MisspelledHeaderInspection() {
+ myRepository = HeaderParserRepository.getInstance();
+ }
+
+ @NotNull
+ @Override
+ public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
+ return new PsiElementVisitor() {
+ @Override
+ public void visitElement(PsiElement element) {
+ if (element instanceof Header) {
+ Header header = (Header)element;
+ Collection<HeaderNameMatch> matches = myRepository.getMatches(header.getName());
+ if (!matches.isEmpty()) {
+ List<HeaderNameSpellingQuickFix> fixes = ContainerUtil.newArrayListWithCapacity(MAX_SUGGESTIONS);
+ for (HeaderNameMatch match : matches) {
+ fixes.add(new HeaderNameSpellingQuickFix(header, match));
+ if (fixes.size() == MAX_SUGGESTIONS) {
+ break;
+ }
+ }
+ holder.registerProblem(
+ header.getNameElement(), ManifestBundle.message("inspection.header.message"),
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, fixes.toArray(new HeaderNameSpellingQuickFix[fixes.size()])
+ );
+ }
+ }
+ }
+ };
+ }
+
+ private static class HeaderNameSpellingQuickFix implements LocalQuickFix {
+ private final Header myHeader;
+ private final String myNewName;
+
+ private HeaderNameSpellingQuickFix(Header header, HeaderNameMatch match) {
+ myHeader = header;
+ myNewName = match.getHeaderName();
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return ManifestBundle.message("inspection.header.fix", myNewName);
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return ManifestBundle.message("inspection.group");
+ }
+
+ @Override
+ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+ myHeader.setName(myNewName);
+ }
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestLexer.java b/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestLexer.java
new file mode 100644
index 0000000..26741c2
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestLexer.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.parser;
+
+import com.intellij.lexer.LexerBase;
+import com.intellij.psi.TokenType;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.lang.manifest.psi.ManifestTokenType;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class ManifestLexer extends LexerBase {
+ private enum State {
+ INITIAL_STATE, WAITING_FOR_HEADER_ASSIGNMENT_STATE, WAITING_FOR_SPACE_AFTER_HEADER_NAME_STATE, BROKEN_LINE
+ }
+
+ private static final Map<Character, IElementType> SPECIAL_CHARACTERS_TOKEN_MAPPING;
+ static {
+ SPECIAL_CHARACTERS_TOKEN_MAPPING = new HashMap<Character, IElementType>();
+ SPECIAL_CHARACTERS_TOKEN_MAPPING.put(':', ManifestTokenType.COLON);
+ SPECIAL_CHARACTERS_TOKEN_MAPPING.put(';', ManifestTokenType.SEMICOLON);
+ SPECIAL_CHARACTERS_TOKEN_MAPPING.put(',', ManifestTokenType.COMMA);
+ SPECIAL_CHARACTERS_TOKEN_MAPPING.put('=', ManifestTokenType.EQUALS);
+ SPECIAL_CHARACTERS_TOKEN_MAPPING.put('(', ManifestTokenType.OPENING_PARENTHESIS_TOKEN);
+ SPECIAL_CHARACTERS_TOKEN_MAPPING.put(')', ManifestTokenType.CLOSING_PARENTHESIS_TOKEN);
+ SPECIAL_CHARACTERS_TOKEN_MAPPING.put('[', ManifestTokenType.OPENING_BRACKET_TOKEN);
+ SPECIAL_CHARACTERS_TOKEN_MAPPING.put(']', ManifestTokenType.CLOSING_BRACKET_TOKEN);
+ SPECIAL_CHARACTERS_TOKEN_MAPPING.put('\"', ManifestTokenType.QUOTE);
+ }
+
+ private CharSequence myBuffer;
+ private int myEndOffset;
+ private int myTokenStart;
+ private int myTokenEnd;
+ private State myCurrentState;
+ private IElementType myTokenType;
+
+ @Override
+ public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
+ this.myBuffer = buffer;
+ this.myEndOffset = endOffset;
+ myCurrentState = State.values()[initialState];
+
+ myTokenStart = startOffset;
+ parseNextToken();
+ }
+
+ @Override
+ public void advance() {
+ myTokenStart = myTokenEnd;
+ parseNextToken();
+ }
+
+ @Override
+ public int getState() {
+ return myCurrentState.ordinal();
+ }
+
+ @Nullable
+ @Override
+ public IElementType getTokenType() {
+ return myTokenType;
+ }
+
+ @Override
+ public int getTokenStart() {
+ return myTokenStart;
+ }
+
+ @Override
+ public int getTokenEnd() {
+ return myTokenEnd;
+ }
+
+ @Override
+ public int getBufferEnd() {
+ return myEndOffset;
+ }
+
+ @Override
+ public CharSequence getBufferSequence() {
+ return myBuffer;
+ }
+
+ private void parseNextToken() {
+ if (myTokenStart < myEndOffset) {
+ if (isNewline(myTokenStart)) {
+ myTokenType = isLineStart(myTokenStart) ? ManifestTokenType.SECTION_END : ManifestTokenType.NEWLINE;
+ myTokenEnd = myTokenStart + 1;
+ myCurrentState = State.INITIAL_STATE;
+ }
+ else if (myCurrentState == State.WAITING_FOR_HEADER_ASSIGNMENT_STATE) {
+ if (isColon(myTokenStart)) {
+ myTokenType = ManifestTokenType.COLON;
+ myCurrentState = State.WAITING_FOR_SPACE_AFTER_HEADER_NAME_STATE;
+ }
+ else {
+ myTokenType = TokenType.BAD_CHARACTER;
+ }
+ myTokenEnd = myTokenStart + 1;
+ }
+ else if (myCurrentState == State.WAITING_FOR_SPACE_AFTER_HEADER_NAME_STATE) {
+ if (isSpace(myTokenStart)) {
+ myTokenEnd = myTokenStart + 1;
+ myTokenType = ManifestTokenType.SIGNIFICANT_SPACE;
+ }
+ else {
+ myTokenEnd = myTokenStart;
+ while (myTokenEnd < myEndOffset && !isSpecialCharacter(myTokenEnd) && !isNewline(myTokenEnd)) {
+ myTokenEnd++;
+ }
+ myTokenType = ManifestTokenType.HEADER_VALUE_PART;
+ }
+ myCurrentState = State.INITIAL_STATE;
+ }
+ else if (isHeaderStart(myTokenStart)) {
+ if (isAlphaNum(myTokenStart)) {
+ myTokenEnd = myTokenStart + 1;
+ while (myTokenEnd < myEndOffset && isHeaderChar(myTokenEnd)) {
+ myTokenEnd++;
+ }
+ myTokenType = ManifestTokenType.HEADER_NAME;
+ myCurrentState = State.WAITING_FOR_HEADER_ASSIGNMENT_STATE;
+ }
+ else {
+ myTokenEnd = myTokenStart + 1;
+ myTokenType = TokenType.BAD_CHARACTER;
+ myCurrentState = State.BROKEN_LINE;
+ }
+ }
+ else if (isContinuationStart(myTokenStart)) {
+ myTokenType = ManifestTokenType.SIGNIFICANT_SPACE;
+ myTokenEnd = myTokenStart + 1;
+ myCurrentState = State.INITIAL_STATE;
+ }
+ else if (myCurrentState == State.BROKEN_LINE) {
+ myTokenEnd = myTokenStart + 1;
+ myTokenType = TokenType.BAD_CHARACTER;
+ }
+ else if (isSpecialCharacter(myTokenStart)) {
+ myTokenType = getTokenTypeForSpecialCharacter(myTokenStart);
+ myTokenEnd = myTokenStart + 1;
+ myCurrentState = State.INITIAL_STATE;
+ }
+ else {
+ myTokenEnd = myTokenStart;
+ while (myTokenEnd < myEndOffset && !isSpecialCharacter(myTokenEnd) && !isNewline(myTokenEnd)) {
+ myTokenEnd++;
+ }
+ myTokenType = ManifestTokenType.HEADER_VALUE_PART;
+ }
+ }
+ else {
+ myTokenType = null;
+ myTokenEnd = myTokenStart;
+ }
+ }
+
+ private boolean isNewline(int position) {
+ return myBuffer.charAt(position) == '\n';
+ }
+
+ private boolean isHeaderStart(int position) {
+ return isLineStart(position) && !Character.isWhitespace(myBuffer.charAt(position));
+ }
+
+ private boolean isAlphaNum(int position) {
+ return Character.isLetterOrDigit(myBuffer.charAt(position));
+ }
+
+ private boolean isHeaderChar(int position) {
+ return isAlphaNum(position) || myBuffer.charAt(position) == '-' || myBuffer.charAt(position) == '_';
+ }
+
+ private boolean isContinuationStart(int position) {
+ return isLineStart(position) && !isHeaderStart(position);
+ }
+
+ private boolean isLineStart(int position) {
+ return position == 0 || isNewline(position - 1);
+ }
+
+ private boolean isSpace(int position) {
+ return myBuffer.charAt(position) == ' ';
+ }
+
+ private boolean isColon(int position) {
+ return myBuffer.charAt(position) == ':';
+ }
+
+ private boolean isSpecialCharacter(int position) {
+ return SPECIAL_CHARACTERS_TOKEN_MAPPING.get(myBuffer.charAt(position)) != null;
+ }
+
+ private IElementType getTokenTypeForSpecialCharacter(int position) {
+ return SPECIAL_CHARACTERS_TOKEN_MAPPING.get(myBuffer.charAt(position));
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestParser.java b/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestParser.java
new file mode 100644
index 0000000..de22144
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestParser.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.parser;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.PsiBuilder;
+import com.intellij.lang.PsiParser;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.psi.TokenType;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.lang.manifest.ManifestBundle;
+import org.jetbrains.lang.manifest.header.HeaderParser;
+import org.jetbrains.lang.manifest.header.HeaderParserRepository;
+import org.jetbrains.lang.manifest.header.impl.StandardHeaderParser;
+import org.jetbrains.lang.manifest.psi.ManifestElementType;
+import org.jetbrains.lang.manifest.psi.ManifestTokenType;
+
+import static com.intellij.lang.PsiBuilderUtil.expect;
+import static com.intellij.util.ObjectUtils.notNull;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class ManifestParser implements PsiParser {
+ public static final TokenSet HEADER_END_TOKENS = TokenSet.create(ManifestTokenType.SECTION_END, ManifestTokenType.HEADER_NAME);
+
+ private final HeaderParserRepository myRepository;
+
+ public ManifestParser() {
+ myRepository = ServiceManager.getService(HeaderParserRepository.class);
+ }
+
+ @NotNull
+ @Override
+ public ASTNode parse(IElementType root, PsiBuilder builder) {
+ builder.setDebugMode(ApplicationManager.getApplication().isUnitTestMode());
+
+ PsiBuilder.Marker rootMarker = builder.mark();
+ while (!builder.eof()) {
+ parseSection(builder);
+ }
+ rootMarker.done(root);
+
+ return builder.getTreeBuilt();
+ }
+
+ private void parseSection(PsiBuilder builder) {
+ PsiBuilder.Marker section = builder.mark();
+
+ while (!builder.eof()) {
+ IElementType tokenType = builder.getTokenType();
+ if (tokenType == ManifestTokenType.HEADER_NAME) {
+ parseHeader(builder);
+ }
+ else if (tokenType == ManifestTokenType.SECTION_END) {
+ builder.advanceLexer();
+ break;
+ }
+ else {
+ PsiBuilder.Marker marker = builder.mark();
+ consumeHeaderValue(builder);
+ marker.error(ManifestBundle.message("manifest.header.expected"));
+ }
+ }
+
+ section.done(ManifestElementType.SECTION);
+ }
+
+ private void parseHeader(PsiBuilder builder) {
+ PsiBuilder.Marker header = builder.mark();
+ String headerName = builder.getTokenText();
+ assert headerName != null : "[" + builder.getOriginalText() + "]@" + builder.getCurrentOffset();
+ builder.advanceLexer();
+
+ PsiBuilder.Marker errors = null;
+ if (builder.getTokenType() == TokenType.BAD_CHARACTER) {
+ errors = builder.mark();
+ while (builder.getTokenType() == TokenType.BAD_CHARACTER) {
+ builder.advanceLexer();
+ }
+ errors.error(ManifestBundle.message("manifest.unexpected.token"));
+ }
+
+ if (builder.getTokenType() == ManifestTokenType.COLON) {
+ builder.advanceLexer();
+
+ if (!expect(builder, ManifestTokenType.SIGNIFICANT_SPACE)) {
+ builder.error(ManifestBundle.message("manifest.whitespace.expected"));
+ }
+
+ HeaderParser headerParser = notNull(myRepository.getHeaderParser(headerName), StandardHeaderParser.INSTANCE);
+ headerParser.parse(builder);
+ }
+ else {
+ PsiBuilder.Marker marker;
+ if (errors == null) {
+ marker = builder.mark();
+ }
+ else {
+ marker = errors.precede();
+ errors.drop();
+ }
+ consumeHeaderValue(builder);
+ marker.error(ManifestBundle.message("manifest.colon.expected"));
+ }
+
+ header.done(ManifestElementType.HEADER);
+ }
+
+ private static void consumeHeaderValue(PsiBuilder builder) {
+ while (!builder.eof() && !HEADER_END_TOKENS.contains(builder.getTokenType())) {
+ builder.advanceLexer();
+ }
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestParserDefinition.java b/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestParserDefinition.java
new file mode 100644
index 0000000..dfe1d97
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/parser/ManifestParserDefinition.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.parser;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.ParserDefinition;
+import com.intellij.lang.PsiParser;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.FileViewProvider;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.IFileElementType;
+import com.intellij.psi.tree.TokenSet;
+import com.intellij.psi.util.PsiUtilCore;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.lang.manifest.psi.Header;
+import org.jetbrains.lang.manifest.psi.ManifestElementType;
+import org.jetbrains.lang.manifest.psi.impl.ManifestFileImpl;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class ManifestParserDefinition implements ParserDefinition {
+ @NotNull
+ @Override
+ public Lexer createLexer(Project project) {
+ return new ManifestLexer();
+ }
+
+ @Override
+ public PsiParser createParser(Project project) {
+ return new ManifestParser();
+ }
+
+ @Override
+ public IFileElementType getFileNodeType() {
+ return ManifestElementType.FILE;
+ }
+
+ @NotNull
+ @Override
+ public TokenSet getWhitespaceTokens() {
+ return TokenSet.EMPTY;
+ }
+
+ @NotNull
+ @Override
+ public TokenSet getCommentTokens() {
+ return TokenSet.EMPTY;
+ }
+
+ @NotNull
+ @Override
+ public TokenSet getStringLiteralElements() {
+ return TokenSet.EMPTY;
+ }
+
+ @NotNull
+ @Override
+ public PsiElement createElement(ASTNode node) {
+ IElementType type = node.getElementType();
+ if (type instanceof ManifestElementType) {
+ return ((ManifestElementType)type).createPsi(node);
+ }
+
+ return PsiUtilCore.NULL_PSI_ELEMENT;
+ }
+
+ @Override
+ public PsiFile createFile(FileViewProvider viewProvider) {
+ return new ManifestFileImpl(viewProvider);
+ }
+
+ @SuppressWarnings("SpellCheckingInspection")
+ @Override
+ public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) {
+ return left.getPsi() instanceof Header || right.getPsi() instanceof Header ?
+ SpaceRequirements.MUST_LINE_BREAK : SpaceRequirements.MUST_NOT;
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/Header.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/Header.java
new file mode 100644
index 0000000..9528a77
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/Header.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi;
+
+import com.intellij.psi.PsiNamedElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public interface Header extends PsiNamedElement {
+ @NotNull
+ @Override
+ String getName();
+
+ @NotNull
+ ManifestToken getNameElement();
+
+ /**
+ * Returns a first header value element if exists.
+ */
+ @Nullable
+ HeaderValue getHeaderValue();
+
+ /**
+ * Returns a list of all header value elements.
+ */
+ @NotNull
+ List<HeaderValue> getHeaderValues();
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/HeaderValue.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/HeaderValue.java
new file mode 100644
index 0000000..98ccb22
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/HeaderValue.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * A manifest header value is a "common ground" for any element
+ * produced by {@link org.jetbrains.lang.manifest.header.HeaderParser} implementations.
+ *
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public interface HeaderValue extends PsiElement {
+ /**
+ * Returns the unwrapped text without the newlines and extra continuation spaces.
+ */
+ @NotNull
+ String getUnwrappedText();
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/HeaderValuePart.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/HeaderValuePart.java
new file mode 100644
index 0000000..624a661
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/HeaderValuePart.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi;
+
+import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * A header value part is either the whole value of a header or the building block for complex structures.
+ *
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public interface HeaderValuePart extends HeaderValue {
+ /**
+ * Returns the range to highlight in the element.
+ */
+ @NotNull
+ TextRange getHighlightingRange();
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/ManifestElementType.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/ManifestElementType.java
new file mode 100644
index 0000000..a6a9d61
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/ManifestElementType.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.IFileElementType;
+import org.jetbrains.lang.manifest.ManifestLanguage;
+import org.jetbrains.lang.manifest.psi.impl.HeaderImpl;
+import org.jetbrains.lang.manifest.psi.impl.HeaderValuePartImpl;
+import org.jetbrains.lang.manifest.psi.impl.SectionImpl;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public abstract class ManifestElementType extends IElementType {
+ public static final IFileElementType FILE = new IFileElementType("ManifestFile", ManifestLanguage.INSTANCE);
+
+ public static final IElementType SECTION = new ManifestElementType("SECTION") {
+ @Override
+ public PsiElement createPsi(ASTNode node) {
+ return new SectionImpl(node);
+ }
+ };
+
+ public static final IElementType HEADER = new ManifestElementType("HEADER") {
+ @Override
+ public PsiElement createPsi(ASTNode node) {
+ return new HeaderImpl(node);
+ }
+ };
+
+ public static final IElementType HEADER_VALUE_PART = new ManifestElementType("HEADER_VALUE_PART") {
+ @Override
+ public PsiElement createPsi(ASTNode node) {
+ return new HeaderValuePartImpl(node);
+ }
+ };
+
+ public ManifestElementType(String name) {
+ super(name, ManifestLanguage.INSTANCE);
+ }
+
+ public abstract PsiElement createPsi(ASTNode node);
+
+ @Override
+ public String toString() {
+ return "MF:" + super.toString();
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/ManifestFile.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/ManifestFile.java
new file mode 100644
index 0000000..a262859
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/ManifestFile.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi;
+
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public interface ManifestFile extends PsiFile {
+ /**
+ * Returns all sections of the file.
+ */
+ @NotNull
+ List<Section> getSections();
+
+ /**
+ * Returns main (first) section if not empty.
+ */
+ @Nullable
+ Section getMainSection();
+
+ /**
+ * Returns all headers from the main section in this file.
+ */
+ @NotNull
+ List<Header> getHeaders();
+
+ /**
+ * Returns the header from the main section with the given name, or null if no such header exists.
+ */
+ @Nullable
+ Header getHeader(@NotNull String name);
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/ManifestToken.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/ManifestToken.java
new file mode 100644
index 0000000..4d5260b
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/ManifestToken.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi;
+
+import com.intellij.psi.PsiElement;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public interface ManifestToken extends PsiElement {
+ ManifestTokenType getTokenType();
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/ManifestTokenType.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/ManifestTokenType.java
new file mode 100644
index 0000000..8a0a70d
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/ManifestTokenType.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.ILeafElementType;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.lang.manifest.ManifestLanguage;
+import org.jetbrains.lang.manifest.psi.impl.ManifestTokenImpl;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public final class ManifestTokenType extends IElementType implements ILeafElementType {
+ public static final ManifestTokenType HEADER_NAME = new ManifestTokenType("HEADER_NAME_TOKEN");
+ public static final ManifestTokenType NEWLINE = new ManifestTokenType("NEWLINE_TOKEN");
+ public static final ManifestTokenType SECTION_END = new ManifestTokenType("SECTION_END_TOKEN");
+ public static final ManifestTokenType COLON = new ManifestTokenType("COLON_TOKEN");
+ public static final ManifestTokenType SEMICOLON = new ManifestTokenType("SEMICOLON_TOKEN");
+ public static final ManifestTokenType EQUALS = new ManifestTokenType("EQUALS_TOKEN");
+ public static final ManifestTokenType COMMA = new ManifestTokenType("COMMA_TOKEN");
+ public static final ManifestTokenType QUOTE = new ManifestTokenType("QUOTE_TOKEN");
+ public static final ManifestTokenType HEADER_VALUE_PART = new ManifestTokenType("HEADER_VALUE_PART_TOKEN");
+ public static final ManifestTokenType SIGNIFICANT_SPACE = new ManifestTokenType("SIGNIFICANT_SPACE_TOKEN");
+ public static final ManifestTokenType OPENING_PARENTHESIS_TOKEN = new ManifestTokenType("OPENING_PARENTHESIS_TOKEN");
+ public static final ManifestTokenType CLOSING_PARENTHESIS_TOKEN = new ManifestTokenType("CLOSING_PARENTHESIS_TOKEN");
+ public static final ManifestTokenType OPENING_BRACKET_TOKEN = new ManifestTokenType("OPENING_BRACKET_TOKEN");
+ public static final ManifestTokenType CLOSING_BRACKET_TOKEN = new ManifestTokenType("CLOSING_BRACKET_TOKEN");
+
+ private ManifestTokenType(@NotNull @NonNls String debugName) {
+ super(debugName, ManifestLanguage.INSTANCE);
+ }
+
+ @NotNull
+ @Override
+ public ASTNode createLeafNode(CharSequence text) {
+ return new ManifestTokenImpl(this, text);
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/Section.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/Section.java
new file mode 100644
index 0000000..d36a6e2
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/Section.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi;
+
+import com.intellij.psi.PsiElement;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public interface Section extends PsiElement {
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/HeaderImpl.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/HeaderImpl.java
new file mode 100644
index 0000000..e14bb98
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/HeaderImpl.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi.impl;
+
+import com.intellij.extapi.psi.ASTWrapperPsiElement;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.impl.source.tree.LeafElement;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.lang.manifest.psi.*;
+
+import java.util.List;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class HeaderImpl extends ASTWrapperPsiElement implements Header {
+ public HeaderImpl(@NotNull ASTNode node) {
+ super(node);
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return getNameElement().getText();
+ }
+
+ @Override
+ public PsiElement setName(@NotNull String name) throws IncorrectOperationException {
+ ((LeafElement)getNameElement().getNode()).replaceWithText(name);
+ return this;
+ }
+
+ @NotNull
+ @Override
+ public ManifestToken getNameElement() {
+ ManifestToken token = (ManifestToken)getNode().findChildByType(ManifestTokenType.HEADER_NAME);
+ assert token != null : getText();
+ return token;
+ }
+
+ @Nullable
+ @Override
+ public HeaderValue getHeaderValue() {
+ return PsiTreeUtil.getChildOfType(this, HeaderValue.class);
+ }
+
+ @NotNull
+ @Override
+ public List<HeaderValue> getHeaderValues() {
+ return PsiTreeUtil.getChildrenOfTypeAsList(this, HeaderValue.class);
+ }
+
+ @Override
+ public String toString() {
+ return "Header:" + getName();
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/HeaderValuePartImpl.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/HeaderValuePartImpl.java
new file mode 100644
index 0000000..a9c7fe2
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/HeaderValuePartImpl.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi.impl;
+
+import com.intellij.extapi.psi.ASTWrapperPsiElement;
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.lang.manifest.psi.ManifestTokenType;
+import org.jetbrains.lang.manifest.header.HeaderParserRepository;
+import org.jetbrains.lang.manifest.psi.HeaderValuePart;
+import org.jetbrains.lang.manifest.psi.ManifestToken;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class HeaderValuePartImpl extends ASTWrapperPsiElement implements HeaderValuePart {
+ private final HeaderParserRepository myRepository;
+
+ public HeaderValuePartImpl(ASTNode node) {
+ super(node);
+ myRepository = ServiceManager.getService(HeaderParserRepository.class);
+ }
+
+ @NotNull
+ @Override
+ public PsiReference[] getReferences() {
+ return getUnwrappedText().isEmpty() ? PsiReference.EMPTY_ARRAY : myRepository.getReferences(this);
+ }
+
+ @NotNull
+ @Override
+ public String getUnwrappedText() {
+ StringBuilder builder = new StringBuilder();
+
+ for (PsiElement element = getFirstChild(); element != null; element = element.getNextSibling()) {
+ if (element instanceof ManifestToken) {
+ ManifestTokenType tokenType = ((ManifestToken)element).getTokenType();
+ if (tokenType == ManifestTokenType.NEWLINE || tokenType == ManifestTokenType.SIGNIFICANT_SPACE) {
+ continue;
+ }
+ }
+ builder.append(element.getText());
+ }
+
+ return builder.toString().trim();
+ }
+
+ @NotNull
+ @Override
+ public TextRange getHighlightingRange() {
+ PsiElement last = getLastChild();
+ if (last instanceof ManifestToken && ((ManifestToken)last).getTokenType() == ManifestTokenType.NEWLINE) {
+ int start = getTextOffset();
+ PsiElement prev = last.getPrevSibling();
+ return new TextRange(start, prev != null ? prev.getTextRange().getEndOffset() : start);
+ }
+ return getTextRange();
+ }
+
+ @Override
+ public String toString() {
+ return "HeaderValuePart";
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/HeaderValuePartManipulator.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/HeaderValuePartManipulator.java
new file mode 100644
index 0000000..156b7b6
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/HeaderValuePartManipulator.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi.impl;
+
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.AbstractElementManipulator;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiFileFactory;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.lang.manifest.ManifestFileTypeFactory;
+import org.jetbrains.lang.manifest.psi.HeaderValue;
+import org.jetbrains.lang.manifest.psi.HeaderValuePart;
+import org.jetbrains.lang.manifest.psi.ManifestFile;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class HeaderValuePartManipulator extends AbstractElementManipulator<HeaderValuePart> {
+ @Override
+ public HeaderValuePart handleContentChange(HeaderValuePart element, TextRange range, String newContent) throws IncorrectOperationException {
+ String text = "HeaderValuePartManipulator: " + range.replace(element.getText(), newContent);
+ PsiFile file = PsiFileFactory.getInstance(element.getProject()).createFileFromText("DUMMY.MF", ManifestFileTypeFactory.MANIFEST, text);
+ HeaderValue value = ((ManifestFile)file).getHeaders().get(0).getHeaderValue();
+ assert value != null : text;
+ return (HeaderValuePart)element.replace(value);
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/ManifestFileImpl.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/ManifestFileImpl.java
new file mode 100644
index 0000000..97f5e35
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/ManifestFileImpl.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi.impl;
+
+import com.intellij.extapi.psi.PsiFileBase;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.psi.FileViewProvider;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.lang.manifest.ManifestFileTypeFactory;
+import org.jetbrains.lang.manifest.ManifestLanguage;
+import org.jetbrains.lang.manifest.psi.Header;
+import org.jetbrains.lang.manifest.psi.ManifestFile;
+import org.jetbrains.lang.manifest.psi.Section;
+
+import java.util.List;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class ManifestFileImpl extends PsiFileBase implements ManifestFile {
+ public ManifestFileImpl(FileViewProvider viewProvider) {
+ super(viewProvider, ManifestLanguage.INSTANCE);
+ }
+
+ @NotNull
+ @Override
+ public FileType getFileType() {
+ return ManifestFileTypeFactory.MANIFEST;
+ }
+
+ @NotNull
+ @Override
+ public List<Section> getSections() {
+ return PsiTreeUtil.getChildrenOfTypeAsList(this, Section.class);
+ }
+
+ @Nullable
+ @Override
+ public Section getMainSection() {
+ return findChildByClass(Section.class);
+ }
+
+ @NotNull
+ @Override
+ public List<Header> getHeaders() {
+ return PsiTreeUtil.getChildrenOfTypeAsList(getFirstChild(), Header.class);
+ }
+
+ @Nullable
+ @Override
+ public Header getHeader(@NotNull String name) {
+ Header child = PsiTreeUtil.findChildOfType(getFirstChild(), Header.class);
+ while (child != null) {
+ if (name.equals(child.getName())) {
+ return child;
+ }
+ child = PsiTreeUtil.getNextSiblingOfType(child, Header.class);
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return "ManifestFile:" + getName();
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/ManifestTokenImpl.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/ManifestTokenImpl.java
new file mode 100644
index 0000000..4bd603a
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/ManifestTokenImpl.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi.impl;
+
+import com.intellij.psi.impl.source.tree.LeafPsiElement;
+import org.jetbrains.lang.manifest.psi.ManifestToken;
+import org.jetbrains.lang.manifest.psi.ManifestTokenType;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class ManifestTokenImpl extends LeafPsiElement implements ManifestToken {
+ public ManifestTokenImpl(ManifestTokenType type, CharSequence text) {
+ super(type, text);
+ }
+
+ @Override
+ public ManifestTokenType getTokenType() {
+ return (ManifestTokenType)getElementType();
+ }
+
+ @Override
+ public String toString() {
+ return "ManifestToken:" + getTokenType();
+ }
+}
diff --git a/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/SectionImpl.java b/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/SectionImpl.java
new file mode 100644
index 0000000..2df8ce1
--- /dev/null
+++ b/java/manifest/src/org/jetbrains/lang/manifest/psi/impl/SectionImpl.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest.psi.impl;
+
+import com.intellij.extapi.psi.ASTWrapperPsiElement;
+import com.intellij.lang.ASTNode;
+import org.jetbrains.lang.manifest.psi.Section;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class SectionImpl extends ASTWrapperPsiElement implements Section {
+ public SectionImpl(ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public String toString() {
+ return "Section";
+ }
+}
diff --git a/java/manifest/test/org/jetbrains/lang/manifest/ManifestCompletionTest.java b/java/manifest/test/org/jetbrains/lang/manifest/ManifestCompletionTest.java
new file mode 100644
index 0000000..a0f1bb9
--- /dev/null
+++ b/java/manifest/test/org/jetbrains/lang/manifest/ManifestCompletionTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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 org.jetbrains.lang.manifest;
+
+import com.intellij.codeInsight.completion.LightCompletionTestCase;
+import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
+
+public class ManifestCompletionTest extends LightCompletionTestCase {
+ public void testHeaderNameCompletionVariants() throws Exception {
+ LightPlatformCodeInsightTestCase.configureFromFileText("MANIFEST.MF", "Specification-V<caret>\n");
+ complete();
+ assertContainsItems("Specification-Vendor", "Specification-Version");
+ assertNotContainItems("Specification-Title");
+ }
+
+ public void testHeaderNameEnterCompletion() throws Exception {
+ LightPlatformCodeInsightTestCase.configureFromFileText("MANIFEST.MF", "Specification-V<caret>\n");
+ complete();
+ assertContainsItems("Specification-Vendor");
+ selectItem(myItems[0], '\n');
+ checkResultByText("Specification-Vendor: <caret>\n");
+ }
+
+ public void testHeaderNameColonCompletion() throws Exception {
+ LightPlatformCodeInsightTestCase.configureFromFileText("MANIFEST.MF", "Specification-V<caret>\n");
+ complete();
+ assertContainsItems("Specification-Vendor");
+ selectItem(myItems[0], ':');
+ checkResultByText("Specification-Vendor: <caret>\n");
+ }
+
+ public void testHeaderNameSpaceCompletion() throws Exception {
+ LightPlatformCodeInsightTestCase.configureFromFileText("MANIFEST.MF", "Specification-V<caret>\n");
+ complete();
+ assertContainsItems("Specification-Vendor");
+ selectItem(myItems[0], ' ');
+ checkResultByText("Specification-Vendor: <caret>\n");
+ }
+}
diff --git a/java/manifest/test/org/jetbrains/lang/manifest/ManifestHighlightingTest.java b/java/manifest/test/org/jetbrains/lang/manifest/ManifestHighlightingTest.java
new file mode 100644
index 0000000..178a75a
--- /dev/null
+++ b/java/manifest/test/org/jetbrains/lang/manifest/ManifestHighlightingTest.java
@@ -0,0 +1,33 @@
+/*
+ * 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 org.jetbrains.lang.manifest;
+
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+
+public class ManifestHighlightingTest extends LightCodeInsightFixtureTestCase {
+ public void testMainClass() {
+ doTest(
+ "Main-Class: <error descr=\"Invalid reference\"></error>\n" +
+ "Main-Class: org.<error descr=\"Cannot resolve\">acme</error>.Main\n" +
+ "Main-Class: java.lang.<error descr=\"Invalid main class\">String</error>\n"
+ );
+ }
+
+ private void doTest(String text) {
+ myFixture.configureByText("MANIFEST.MF", text);
+ myFixture.checkHighlighting(true, false, false);
+ }
+}
diff --git a/java/manifest/test/org/jetbrains/lang/manifest/ManifestLexerTest.java b/java/manifest/test/org/jetbrains/lang/manifest/ManifestLexerTest.java
new file mode 100644
index 0000000..8966131
--- /dev/null
+++ b/java/manifest/test/org/jetbrains/lang/manifest/ManifestLexerTest.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.lang.manifest;
+
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.lang.manifest.parser.ManifestLexer;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class ManifestLexerTest {
+ @Test
+ public void testSpaces() {
+ doTest(" ",
+
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN (' ')");
+ }
+
+ @Test
+ public void testRandomText() {
+ doTest("some text\nsome more text",
+
+ "HEADER_NAME_TOKEN ('some')\n" +
+ "BAD_CHARACTER (' ')\n" +
+ "BAD_CHARACTER ('t')\n" +
+ "BAD_CHARACTER ('e')\n" +
+ "BAD_CHARACTER ('x')\n" +
+ "BAD_CHARACTER ('t')\n" +
+ "NEWLINE_TOKEN ('\n')\n" +
+ "HEADER_NAME_TOKEN ('some')\n" +
+ "BAD_CHARACTER (' ')\n" +
+ "BAD_CHARACTER ('m')\n" +
+ "BAD_CHARACTER ('o')\n" +
+ "BAD_CHARACTER ('r')\n" +
+ "BAD_CHARACTER ('e')\n" +
+ "BAD_CHARACTER (' ')\n" +
+ "BAD_CHARACTER ('t')\n" +
+ "BAD_CHARACTER ('e')\n" +
+ "BAD_CHARACTER ('x')\n" +
+ "BAD_CHARACTER ('t')");
+ }
+
+ @Test
+ public void testValid() {
+ doTest("Name: Value",
+
+ "HEADER_NAME_TOKEN ('Name')\n" +
+ "COLON_TOKEN (':')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN ('Value')");
+ }
+
+ @Test
+ public void testInvalidSpaceBeforeColon() {
+ doTest("Name : Value",
+
+ "HEADER_NAME_TOKEN ('Name')\n" +
+ "BAD_CHARACTER (' ')\n" +
+ "COLON_TOKEN (':')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN ('Value')");
+ }
+
+ @Test
+ public void testMissingSpaceAfterColon() {
+ doTest("Name:Value",
+
+ "HEADER_NAME_TOKEN ('Name')\n" +
+ "COLON_TOKEN (':')\n" +
+ "HEADER_VALUE_PART_TOKEN ('Value')");
+ }
+
+ @Test
+ public void testTwoHeaders() {
+ doTest("Name: Value\nName2: Value2",
+
+ "HEADER_NAME_TOKEN ('Name')\n" +
+ "COLON_TOKEN (':')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN ('Value')\n" +
+ "NEWLINE_TOKEN ('\n')\n" +
+ "HEADER_NAME_TOKEN ('Name2')\n" +
+ "COLON_TOKEN (':')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN ('Value2')");
+ }
+
+ @Test
+ public void testContinuation() {
+ doTest("Name: Value\n Value2",
+
+ "HEADER_NAME_TOKEN ('Name')\n" +
+ "COLON_TOKEN (':')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN ('Value')\n" +
+ "NEWLINE_TOKEN ('\n')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN ('Value2')");
+ }
+
+ @Test
+ public void testSection() {
+ doTest("Name: Value\n\nName2: Value2",
+
+ "HEADER_NAME_TOKEN ('Name')\n" +
+ "COLON_TOKEN (':')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN ('Value')\n" +
+ "NEWLINE_TOKEN ('\n')\n" +
+ "SECTION_END_TOKEN ('\n')\n" +
+ "HEADER_NAME_TOKEN ('Name2')\n" +
+ "COLON_TOKEN (':')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN ('Value2')");
+ }
+
+ @Test
+ public void testNoIgnoredSpaces() {
+ doTest("Name: Value \n Value2",
+
+ "HEADER_NAME_TOKEN ('Name')\n" +
+ "COLON_TOKEN (':')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN ('Value ')\n" +
+ "NEWLINE_TOKEN ('\n')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN (' Value2')");
+ }
+
+ @Test
+ public void testSpecialCharacters() {
+ doTest("Name: ;:=,\"",
+
+ "HEADER_NAME_TOKEN ('Name')\n" +
+ "COLON_TOKEN (':')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "SEMICOLON_TOKEN (';')\n" +
+ "COLON_TOKEN (':')\n" +
+ "EQUALS_TOKEN ('=')\n" +
+ "COMMA_TOKEN (',')\n" +
+ "QUOTE_TOKEN ('\"')");
+ }
+
+ @Test
+ public void testErrorEndsAtNewline() {
+ doTest("Name \n value",
+
+ "HEADER_NAME_TOKEN ('Name')\n" +
+ "BAD_CHARACTER (' ')\n" +
+ "NEWLINE_TOKEN ('\n')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN ('value')");
+ }
+
+ @Test
+ public void testNewlineBetweenSpecialChars() {
+ doTest("Name: ab;dir:\n =value\n",
+
+ "HEADER_NAME_TOKEN ('Name')\n" +
+ "COLON_TOKEN (':')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN ('ab')\n" +
+ "SEMICOLON_TOKEN (';')\n" +
+ "HEADER_VALUE_PART_TOKEN ('dir')\n" +
+ "COLON_TOKEN (':')\n" +
+ "NEWLINE_TOKEN ('\n')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "EQUALS_TOKEN ('=')\n" +
+ "HEADER_VALUE_PART_TOKEN ('value')\n" +
+ "NEWLINE_TOKEN ('\n')");
+ }
+
+ @Test
+ public void testBadHeaderStart() {
+ doTest("Name: ab;dir:\n" +
+ "=value;a:=b\n",
+
+ "HEADER_NAME_TOKEN ('Name')\n" +
+ "COLON_TOKEN (':')\n" +
+ "SIGNIFICANT_SPACE_TOKEN (' ')\n" +
+ "HEADER_VALUE_PART_TOKEN ('ab')\n" +
+ "SEMICOLON_TOKEN (';')\n" +
+ "HEADER_VALUE_PART_TOKEN ('dir')\n" +
+ "COLON_TOKEN (':')\n" +
+ "NEWLINE_TOKEN ('\n')\n" +
+ "BAD_CHARACTER ('=')\n" +
+ "BAD_CHARACTER ('v')\n" +
+ "BAD_CHARACTER ('a')\n" +
+ "BAD_CHARACTER ('l')\n" +
+ "BAD_CHARACTER ('u')\n" +
+ "BAD_CHARACTER ('e')\n" +
+ "BAD_CHARACTER (';')\n" +
+ "BAD_CHARACTER ('a')\n" +
+ "BAD_CHARACTER (':')\n" +
+ "BAD_CHARACTER ('=')\n" +
+ "BAD_CHARACTER ('b')\n" +
+ "NEWLINE_TOKEN ('\n')");
+ }
+
+ private static void doTest(String text, String expected) {
+ ManifestLexer lexer = new ManifestLexer();
+ lexer.start(text);
+
+ StringBuilder actual = new StringBuilder();
+ IElementType token;
+ while ((token = lexer.getTokenType()) != null) {
+ actual.append(token).append(" ('").append(lexer.getTokenText()).append("')\n");
+ lexer.advance();
+ }
+
+ assertEquals(expected.trim(), actual.toString().trim());
+ }
+}
diff --git a/java/manifest/test/org/jetbrains/lang/manifest/ManifestParserTest.java b/java/manifest/test/org/jetbrains/lang/manifest/ManifestParserTest.java
new file mode 100644
index 0000000..411fbc8
--- /dev/null
+++ b/java/manifest/test/org/jetbrains/lang/manifest/ManifestParserTest.java
@@ -0,0 +1,354 @@
+/*
+ * 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 org.jetbrains.lang.manifest;
+
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.impl.DebugUtil;
+import com.intellij.testFramework.LightIdeaTestCase;
+import com.intellij.testFramework.LightPlatformTestCase;
+import junit.framework.Assert;
+
+/**
+ * @author Robert F. Beeger (robert@beeger.net)
+ */
+public class ManifestParserTest extends LightIdeaTestCase {
+ public void testEmpty() {
+ doTest("",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " <empty list>\n");
+ }
+
+ public void testSpaces() {
+ doTest(" ",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " PsiErrorElement:Header expected\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN(' ')\n");
+ }
+
+ public void testRandomText() {
+ doTest("some text\nmore text",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:some\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('some')\n" +
+ " PsiErrorElement:':' expected\n" +
+ " PsiElement(BAD_CHARACTER)(' ')\n" +
+ " PsiElement(BAD_CHARACTER)('t')\n" +
+ " PsiElement(BAD_CHARACTER)('e')\n" +
+ " PsiElement(BAD_CHARACTER)('x')\n" +
+ " PsiElement(BAD_CHARACTER)('t')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n" +
+ " Header:more\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('more')\n" +
+ " PsiErrorElement:':' expected\n" +
+ " PsiElement(BAD_CHARACTER)(' ')\n" +
+ " PsiElement(BAD_CHARACTER)('t')\n" +
+ " PsiElement(BAD_CHARACTER)('e')\n" +
+ " PsiElement(BAD_CHARACTER)('x')\n" +
+ " PsiElement(BAD_CHARACTER)('t')\n");
+ }
+
+ public void testNoHeader() {
+ doTest(" some text",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " PsiErrorElement:Header expected\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('some text')\n");
+ }
+
+ public void testBadHeaderStart() {
+ doTest("Name: ab;dir:\n" +
+ "=value;a:=b\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Name\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Name')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('ab')\n" +
+ " ManifestToken:SEMICOLON_TOKEN(';')\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('dir')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n" +
+ " PsiErrorElement:Header expected\n" +
+ " PsiElement(BAD_CHARACTER)('=')\n" +
+ " PsiElement(BAD_CHARACTER)('v')\n" +
+ " PsiElement(BAD_CHARACTER)('a')\n" +
+ " PsiElement(BAD_CHARACTER)('l')\n" +
+ " PsiElement(BAD_CHARACTER)('u')\n" +
+ " PsiElement(BAD_CHARACTER)('e')\n" +
+ " PsiElement(BAD_CHARACTER)(';')\n" +
+ " PsiElement(BAD_CHARACTER)('a')\n" +
+ " PsiElement(BAD_CHARACTER)(':')\n" +
+ " PsiElement(BAD_CHARACTER)('=')\n" +
+ " PsiElement(BAD_CHARACTER)('b')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n");
+ }
+
+ public void testNewLines() {
+ doTest("\n\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " ManifestToken:SECTION_END_TOKEN('\\n')\n" +
+ " Section\n" +
+ " ManifestToken:SECTION_END_TOKEN('\\n')\n");
+ }
+
+ public void testSimple() {
+ doTest("Manifest-Version: 1.0\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Manifest-Version\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Manifest-Version')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('1.0')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n");
+ }
+
+ public void testExtraSpaceInHeaderAssignment() {
+ doTest("Manifest-Version : 1.0\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Manifest-Version\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Manifest-Version')\n" +
+ " PsiErrorElement:Unexpected token\n" +
+ " PsiElement(BAD_CHARACTER)(' ')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('1.0')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n");
+ }
+
+ public void testMissingSpaceInHeaderAssignment() {
+ doTest("Specification-Vendor:name\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Specification-Vendor\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Specification-Vendor')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " PsiErrorElement:Whitespace expected\n" +
+ " <empty list>\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('name')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n");
+ }
+
+ public void testSimpleWithNewLines() {
+ doTest("Manifest-Version: 1.0\n\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Manifest-Version\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Manifest-Version')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('1.0')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n" +
+ " ManifestToken:SECTION_END_TOKEN('\\n')\n");
+ }
+
+ public void testSimpleIncomplete() {
+ doTest("Manifest-Version:",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Manifest-Version\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Manifest-Version')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " PsiErrorElement:Whitespace expected\n" +
+ " <empty list>\n" +
+ " HeaderValuePart\n" +
+ " <empty list>\n");
+ }
+
+ public void testSimpleIncompleteWithNewLine() {
+ doTest("Manifest-Version:\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Manifest-Version\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Manifest-Version')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " PsiErrorElement:Whitespace expected\n" +
+ " <empty list>\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n");
+ }
+
+ public void testSimpleIncompleteWithNewLines() {
+ doTest("Manifest-Version:\n\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Manifest-Version\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Manifest-Version')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " PsiErrorElement:Whitespace expected\n" +
+ " <empty list>\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n" +
+ " ManifestToken:SECTION_END_TOKEN('\\n')\n");
+ }
+
+ public void testSimpleWithContinuation() {
+ doTest("Specification-Vendor: Acme\n" +
+ " Company\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Specification-Vendor\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Specification-Vendor')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('Acme')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('Company')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n");
+ }
+
+ public void testSimpleWithQuotedValue() {
+ doTest("Implementation-Vendor: \"Apache Software Foundation\"\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Implementation-Vendor\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Implementation-Vendor')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:QUOTE_TOKEN('\"')\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('Apache Software Foundation')\n" +
+ " ManifestToken:QUOTE_TOKEN('\"')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n");
+ }
+
+ public void testSimpleHeaderValueStartsWithColon() {
+ doTest("Implementation-Vendor: :value\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Implementation-Vendor\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Implementation-Vendor')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('value')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n");
+ }
+
+ public void testSimpleHeaderValueStartsWithEquals() {
+ doTest("Implementation-Vendor: =value\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Implementation-Vendor\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Implementation-Vendor')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:EQUALS_TOKEN('=')\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('value')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n");
+ }
+
+ public void testSimpleHeaderValueStartsWithSemicolon() {
+ doTest("Implementation-Vendor: ;value\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Implementation-Vendor\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Implementation-Vendor')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:SEMICOLON_TOKEN(';')\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('value')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n");
+ }
+
+ public void testTwoHeaders() {
+ doTest("Manifest-Version: 1.0\n" +
+ "Ant-Version: Apache Ant 1.6.5\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Manifest-Version\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Manifest-Version')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('1.0')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n" +
+ " Header:Ant-Version\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Ant-Version')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('Apache Ant 1.6.5')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n");
+ }
+
+ public void testTwoSections() {
+ doTest("Manifest-Version: 1.0\n" +
+ "\n" +
+ "Ant-Version: Apache Ant 1.6.5\n\n",
+
+ "ManifestFile:MANIFEST.MF\n" +
+ " Section\n" +
+ " Header:Manifest-Version\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Manifest-Version')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('1.0')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n" +
+ " ManifestToken:SECTION_END_TOKEN('\\n')\n" +
+ " Section\n" +
+ " Header:Ant-Version\n" +
+ " ManifestToken:HEADER_NAME_TOKEN('Ant-Version')\n" +
+ " ManifestToken:COLON_TOKEN(':')\n" +
+ " ManifestToken:SIGNIFICANT_SPACE_TOKEN(' ')\n" +
+ " HeaderValuePart\n" +
+ " ManifestToken:HEADER_VALUE_PART_TOKEN('Apache Ant 1.6.5')\n" +
+ " ManifestToken:NEWLINE_TOKEN('\\n')\n" +
+ " ManifestToken:SECTION_END_TOKEN('\\n')\n");
+ }
+
+ private static void doTest(String source, String expected) {
+ PsiFile file = LightPlatformTestCase.createLightFile("MANIFEST.MF", source);
+ Assert.assertEquals(expected, DebugUtil.psiToString(file, true));
+ }
+}
diff --git a/java/manifest/test/org/jetbrains/lang/manifest/ManifestPsiTest.java b/java/manifest/test/org/jetbrains/lang/manifest/ManifestPsiTest.java
new file mode 100644
index 0000000..64d8fc2
--- /dev/null
+++ b/java/manifest/test/org/jetbrains/lang/manifest/ManifestPsiTest.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 org.jetbrains.lang.manifest;
+
+import com.intellij.psi.PsiFile;
+import com.intellij.testFramework.LightIdeaTestCase;
+import com.intellij.testFramework.LightPlatformTestCase;
+import junit.framework.Assert;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.lang.manifest.psi.Header;
+import org.jetbrains.lang.manifest.psi.HeaderValue;
+import org.jetbrains.lang.manifest.psi.ManifestFile;
+
+public class ManifestPsiTest extends LightIdeaTestCase {
+ public void testFile() {
+ ManifestFile file = createFile("");
+ Assert.assertEquals(0, file.getSections().size());
+ Assert.assertNull(file.getMainSection());
+ Assert.assertEquals(0, file.getHeaders().size());
+
+ file = createFile("Header: value\n\nAnother-Header: another value\n");
+ Assert.assertEquals(2, file.getSections().size());
+ Assert.assertNotNull(file.getMainSection());
+ Assert.assertEquals(1, file.getHeaders().size());
+ Assert.assertNotNull(file.getHeader("Header"));
+ Assert.assertNull(file.getHeader("Another-Header"));
+ }
+
+ public void testHeader() {
+ ManifestFile file = createFile("Header: value\nEmpty-Header:\nBad-Header\n");
+ assertHeaderValue(file, "Header", "value");
+ assertHeaderValue(file, "Empty-Header", "");
+ assertHeaderValue(file, "Bad-Header", null);
+ }
+
+ private static ManifestFile createFile(String text) {
+ PsiFile file = LightPlatformTestCase.createLightFile("MANIFEST.MF", text);
+ assert file instanceof ManifestFile : file;
+ return (ManifestFile)file;
+ }
+
+ private static void assertHeaderValue(ManifestFile file, String name, @Nullable String expected) {
+ Header header = file.getHeader(name);
+ Assert.assertNotNull(header);
+
+ HeaderValue value = header.getHeaderValue();
+ if (expected == null) {
+ Assert.assertNull(value);
+ }
+ else {
+ Assert.assertNotNull(value);
+ Assert.assertEquals(expected, value.getUnwrappedText());
+ }
+ }
+}
diff --git a/java/manifest/test/org/jetbrains/lang/manifest/MissingFinalNewlineInspectionTest.java b/java/manifest/test/org/jetbrains/lang/manifest/MissingFinalNewlineInspectionTest.java
new file mode 100644
index 0000000..a55b938
--- /dev/null
+++ b/java/manifest/test/org/jetbrains/lang/manifest/MissingFinalNewlineInspectionTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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 org.jetbrains.lang.manifest;
+
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+import junit.framework.Assert;
+import org.jetbrains.lang.manifest.highlighting.MissingFinalNewlineInspection;
+
+public class MissingFinalNewlineInspectionTest extends LightCodeInsightFixtureTestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ myFixture.enableInspections(new MissingFinalNewlineInspection());
+ }
+
+ public void testEmptyFile() {
+ myFixture.configureByText(ManifestFileTypeFactory.MANIFEST, "");
+ Assert.assertEquals(0, myFixture.getAvailableIntentions().size());
+ }
+
+ public void testNoProblem() {
+ myFixture.configureByText(ManifestFileTypeFactory.MANIFEST, "Manifest-Version: 1.0\n");
+ Assert.assertEquals(0, myFixture.getAvailableIntentions().size());
+ }
+
+ public void testFix() {
+ myFixture.configureByText(ManifestFileTypeFactory.MANIFEST, "Manifest-Version: 1.0");
+ IntentionAction intention = myFixture.findSingleIntention(ManifestBundle.message("inspection.newline.fix"));
+ myFixture.launchAction(intention);
+ myFixture.checkResult("Manifest-Version: 1.0\n");
+ }
+}
diff --git a/java/manifest/test/org/jetbrains/lang/manifest/MisspelledHeaderInspectionTest.java b/java/manifest/test/org/jetbrains/lang/manifest/MisspelledHeaderInspectionTest.java
new file mode 100644
index 0000000..844ed05
--- /dev/null
+++ b/java/manifest/test/org/jetbrains/lang/manifest/MisspelledHeaderInspectionTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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 org.jetbrains.lang.manifest;
+
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+import junit.framework.Assert;
+import org.jetbrains.lang.manifest.highlighting.MisspelledHeaderInspection;
+
+import java.util.List;
+
+public class MisspelledHeaderInspectionTest extends LightCodeInsightFixtureTestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ myFixture.enableInspections(new MisspelledHeaderInspection());
+ }
+
+ public void testNoProblem() {
+ myFixture.configureByText(ManifestFileTypeFactory.MANIFEST, "Manifest-Version: 1.0\n");
+ Assert.assertEquals(0, myFixture.getAvailableIntentions().size());
+ }
+
+ public void testFix() {
+ myFixture.configureByText(ManifestFileTypeFactory.MANIFEST, "ManifestVersion: 1.0\n");
+ List<IntentionAction> intentions = myFixture.filterAvailableIntentions("Change to");
+ Assert.assertTrue(intentions.size() > 0);
+ myFixture.launchAction(intentions.get(0));
+ myFixture.checkResult("Manifest-Version: 1.0\n");
+ }
+}
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 e8afbc6..7426653 100644
--- a/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java
+++ b/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java
@@ -18,6 +18,8 @@
import com.intellij.codeInsight.CodeInsightActionHandler;
import com.intellij.codeInsight.actions.CodeInsightAction;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -25,13 +27,18 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public class BaseGenerateAction extends CodeInsightAction {
+public class BaseGenerateAction extends CodeInsightAction implements GenerateActionPopupTemplateInjector {
private final CodeInsightActionHandler myHandler;
public BaseGenerateAction(CodeInsightActionHandler handler) {
myHandler = handler;
}
+ @Nullable
+ public AnAction createEditTemplateAction(DataContext dataContext) {
+ return null;
+ }
+
@NotNull
@Override
protected final CodeInsightActionHandler getHandler() {
diff --git a/java/openapi/src/com/intellij/codeInsight/quickfix/ChangeVariableTypeQuickFixProvider.java b/java/openapi/src/com/intellij/codeInsight/quickfix/ChangeVariableTypeQuickFixProvider.java
index 5f0113e..f420e78 100644
--- a/java/openapi/src/com/intellij/codeInsight/quickfix/ChangeVariableTypeQuickFixProvider.java
+++ b/java/openapi/src/com/intellij/codeInsight/quickfix/ChangeVariableTypeQuickFixProvider.java
@@ -24,9 +24,11 @@
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiVariable;
+import org.jetbrains.annotations.NotNull;
public interface ChangeVariableTypeQuickFixProvider {
ExtensionPointName<ChangeVariableTypeQuickFixProvider> EP_NAME = ExtensionPointName.create("com.intellij.codeInsight.changeVariableTypeQuickFixProvider");
- IntentionAction[] getFixes(PsiVariable variable, PsiType toReturn);
+ @NotNull
+ IntentionAction[] getFixes(@NotNull PsiVariable variable, @NotNull PsiType toReturn);
}
\ No newline at end of file
diff --git a/java/remote-servers/remote-servers-java.iml b/java/remote-servers/remote-servers-java.iml
new file mode 100644
index 0000000..994a29f
--- /dev/null
+++ b/java/remote-servers/remote-servers-java.iml
@@ -0,0 +1,20 @@
+<?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" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="remote-servers-api" />
+ <orderEntry type="module" module-name="debugger-impl" />
+ <orderEntry type="module" module-name="core-api" />
+ <orderEntry type="module" module-name="lang-api" />
+ <orderEntry type="module" module-name="xdebugger-api" />
+ <orderEntry type="module" module-name="lang-impl" />
+ <orderEntry type="module" module-name="execution-openapi" />
+ <orderEntry type="module" module-name="remote-servers-impl" scope="RUNTIME" />
+ </component>
+</module>
+
diff --git a/java/remote-servers/src/com/intellij/remoteServer/impl/runtime/deployment/debug/JavaDebuggerLauncherImpl.java b/java/remote-servers/src/com/intellij/remoteServer/impl/runtime/deployment/debug/JavaDebuggerLauncherImpl.java
new file mode 100644
index 0000000..3ec24ef
--- /dev/null
+++ b/java/remote-servers/src/com/intellij/remoteServer/impl/runtime/deployment/debug/JavaDebuggerLauncherImpl.java
@@ -0,0 +1,143 @@
+package com.intellij.remoteServer.impl.runtime.deployment.debug;
+
+import com.intellij.debugger.DebugEnvironment;
+import com.intellij.debugger.DebugUIEnvironment;
+import com.intellij.debugger.engine.RemoteDebugProcessHandler;
+import com.intellij.debugger.ui.DebuggerPanelsManager;
+import com.intellij.diagnostic.logging.LogFilesManager;
+import com.intellij.execution.*;
+import com.intellij.execution.configurations.RemoteConnection;
+import com.intellij.execution.configurations.RunProfile;
+import com.intellij.execution.executors.DefaultDebugExecutor;
+import com.intellij.execution.impl.ConsoleViewImpl;
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.execution.runners.RunContentBuilder;
+import com.intellij.execution.ui.RunContentDescriptor;
+import com.intellij.execution.ui.actions.CloseAction;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.remoteServer.configuration.RemoteServer;
+import com.intellij.remoteServer.runtime.deployment.debug.JavaDebugConnectionData;
+import com.intellij.remoteServer.runtime.deployment.debug.JavaDebuggerLauncher;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * @author nik
+ */
+public class JavaDebuggerLauncherImpl extends JavaDebuggerLauncher {
+ private static final Logger LOG = Logger.getInstance(JavaDebuggerLauncherImpl.class);
+
+ @Override
+ public void startDebugSession(@NotNull JavaDebugConnectionData info, @NotNull ExecutionEnvironment executionEnvironment, RemoteServer<?> server)
+ throws ExecutionException {
+ final Project project = executionEnvironment.getProject();
+ Executor executor = DefaultDebugExecutor.getDebugExecutorInstance();
+ final DebuggerPanelsManager manager = DebuggerPanelsManager.getInstance(project);
+ final RemoteConnection remoteConnection = new RemoteConnection(true, info.getHost(), String.valueOf(info.getPort()), false);
+ DebugEnvironment debugEnvironment = new RemoteServerDebugEnvironment(project, remoteConnection, executionEnvironment.getRunProfile());
+ DebugUIEnvironment debugUIEnvironment = new RemoteServerDebugUIEnvironment(debugEnvironment, executionEnvironment);
+ RunContentDescriptor debugContentDescriptor = manager.attachVirtualMachine(debugUIEnvironment);
+ LOG.assertTrue(debugContentDescriptor != null);
+ ProcessHandler processHandler = debugContentDescriptor.getProcessHandler();
+ LOG.assertTrue(processHandler != null);
+ processHandler.startNotify();
+ ExecutionManager.getInstance(project).getContentManager().showRunContent(executor, debugContentDescriptor,
+ executionEnvironment.getContentToReuse());
+ }
+
+ private static class RemoteServerDebugUIEnvironment implements DebugUIEnvironment {
+ private final DebugEnvironment myEnvironment;
+ private final ExecutionEnvironment myExecutionEnvironment;
+
+ public RemoteServerDebugUIEnvironment(DebugEnvironment environment, ExecutionEnvironment executionEnvironment) {
+ myEnvironment = environment;
+ myExecutionEnvironment = executionEnvironment;
+ }
+
+ @Override
+ public DebugEnvironment getEnvironment() {
+ return myEnvironment;
+ }
+
+ @Nullable
+ @Override
+ public RunContentDescriptor getReuseContent() {
+ return myExecutionEnvironment.getContentToReuse();
+ }
+
+ @Nullable
+ @Override
+ public Icon getIcon() {
+ return myExecutionEnvironment.getRunProfile().getIcon();
+ }
+
+ @Override
+ public void initLogs(RunContentDescriptor content, LogFilesManager logFilesManager) {
+ }
+
+ @Override
+ public void initActions(RunContentDescriptor content, DefaultActionGroup actionGroup) {
+ actionGroup.add(new CloseAction(myExecutionEnvironment.getExecutor(), content, myExecutionEnvironment.getProject()));
+ }
+
+ @Nullable
+ @Override
+ public RunProfile getRunProfile() {
+ return myExecutionEnvironment.getRunProfile();
+ }
+ }
+
+ private static class RemoteServerDebugEnvironment implements DebugEnvironment {
+ private final Project myProject;
+ private final GlobalSearchScope mySearchScope;
+ private final RemoteConnection myRemoteConnection;
+ private final RunProfile myRunProfile;
+
+ public RemoteServerDebugEnvironment(Project project, RemoteConnection remoteConnection, RunProfile runProfile) {
+ myProject = project;
+ mySearchScope = RunContentBuilder.createSearchScope(project, runProfile);
+ myRemoteConnection = remoteConnection;
+ myRunProfile = runProfile;
+ }
+
+ @Nullable
+ @Override
+ public ExecutionResult createExecutionResult() throws ExecutionException {
+ ConsoleViewImpl consoleView = new ConsoleViewImpl(myProject, false);
+ RemoteDebugProcessHandler process = new RemoteDebugProcessHandler(myProject);
+ consoleView.attachToProcess(process);
+ return new DefaultExecutionResult(consoleView, process);
+ }
+
+ @Override
+ public GlobalSearchScope getSearchScope() {
+ return mySearchScope;
+ }
+
+ @Override
+ public boolean isRemote() {
+ return true;
+ }
+
+ @Override
+ public RemoteConnection getRemoteConnection() {
+ return myRemoteConnection;
+ }
+
+ @Override
+ public boolean isPollConnection() {
+ return true;
+ }
+
+ @Override
+ public String getSessionName() {
+ return myRunProfile.getName();
+ }
+ }
+}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/client/ProtobufClientMessageHandler.java b/jps/jps-builders/src/org/jetbrains/jps/client/ProtobufClientMessageHandler.java
index 1134d30..d6b428d 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/client/ProtobufClientMessageHandler.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/client/ProtobufClientMessageHandler.java
@@ -16,12 +16,12 @@
package org.jetbrains.jps.client;
import com.google.protobuf.MessageLite;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelHandler;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.api.RequestFuture;
+import org.jetbrains.jps.javac.JavacRemoteProto;
import java.util.ArrayList;
import java.util.UUID;
@@ -32,7 +32,8 @@
* @author Eugene Zhuravlev
* Date: 1/22/12
*/
-final class ProtobufClientMessageHandler<T extends ProtobufResponseHandler> extends SimpleChannelHandler {
+@ChannelHandler.Sharable
+final class ProtobufClientMessageHandler<T extends ProtobufResponseHandler> extends SimpleChannelInboundHandler<MessageLite> {
private final ConcurrentHashMap<UUID, RequestFuture<T>> myHandlers = new ConcurrentHashMap<UUID, RequestFuture<T>>();
@NotNull
private final UUIDGetter myUuidGetter;
@@ -45,8 +46,9 @@
myAsyncExec = asyncExec;
}
- public final void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
- final UUID messageUUID = myUuidGetter.getSessionUUID(e);
+ @Override
+ public final void channelRead0(ChannelHandlerContext context, MessageLite message) throws Exception {
+ final UUID messageUUID = myUuidGetter.getSessionUUID((JavacRemoteProto.Message)message);
final RequestFuture<T> future = myHandlers.get(messageUUID);
final T handler = future != null ? future.getMessageHandler() : null;
if (handler == null) {
@@ -55,7 +57,7 @@
else {
boolean terminateSession = false;
try {
- terminateSession = handler.handleMessage((MessageLite)e.getMessage());
+ terminateSession = handler.handleMessage(message);
}
catch (Exception ex) {
terminateSession = true;
@@ -78,8 +80,9 @@
try {
handler.sessionTerminated();
}
- catch (Throwable ignored) {
- ignored.printStackTrace();
+ catch (Throwable e) {
+ //noinspection CallToPrintStackTrace
+ e.printStackTrace();
}
}
}
@@ -89,30 +92,26 @@
}
}
- public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
- try {
- super.channelClosed(ctx, e);
- }
- finally {
- for (UUID uuid : new ArrayList<UUID>(myHandlers.keySet())) {
- terminateSession(uuid);
- }
- }
- }
-
@Override
- public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+ public void channelInactive(ChannelHandlerContext context) throws Exception {
try {
- super.channelDisconnected(ctx, e);
+ super.channelInactive(context);
}
finally {
- // make sure the client is in disconnected state
- myAsyncExec.execute(new Runnable() {
- @Override
- public void run() {
- myClient.disconnect();
+ try {
+ for (UUID uuid : new ArrayList<UUID>(myHandlers.keySet())) {
+ terminateSession(uuid);
}
- });
+ }
+ finally {
+ // make sure the client is in disconnected state
+ myAsyncExec.execute(new Runnable() {
+ @Override
+ public void run() {
+ myClient.disconnect();
+ }
+ });
+ }
}
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/client/SimpleProtobufClient.java b/jps/jps-builders/src/org/jetbrains/jps/client/SimpleProtobufClient.java
index 06f4175..19246ee 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/client/SimpleProtobufClient.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/client/SimpleProtobufClient.java
@@ -17,17 +17,17 @@
import com.google.protobuf.MessageLite;
import com.intellij.openapi.diagnostic.Logger;
-import org.jboss.netty.bootstrap.ClientBootstrap;
-import org.jboss.netty.channel.*;
-import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
-import org.jboss.netty.handler.codec.protobuf.ProtobufDecoder;
-import org.jboss.netty.handler.codec.protobuf.ProtobufEncoder;
-import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
-import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.*;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.codec.protobuf.ProtobufDecoder;
+import io.netty.handler.codec.protobuf.ProtobufEncoder;
+import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
+import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.api.RequestFuture;
-import java.net.InetSocketAddress;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference;
@@ -39,28 +39,27 @@
public class SimpleProtobufClient<T extends ProtobufResponseHandler> {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.client.SimpleProtobufClient");
- private static enum State {
+ private enum State {
DISCONNECTED, CONNECTING, CONNECTED, DISCONNECTING
}
private final AtomicReference<State> myState = new AtomicReference<State>(State.DISCONNECTED);
- protected final ChannelPipelineFactory myPipelineFactory;
- protected final ChannelFactory myChannelFactory;
+ protected final ChannelInitializer myChannelInitializer;
+ protected final EventLoopGroup myEventLoopGroup;
protected volatile ChannelFuture myConnectFuture;
private final ProtobufClientMessageHandler<T> myMessageHandler;
public SimpleProtobufClient(final MessageLite msgDefaultInstance, final Executor asyncExec, final UUIDGetter uuidGetter) {
myMessageHandler = new ProtobufClientMessageHandler<T>(uuidGetter, this, asyncExec);
- myChannelFactory = new NioClientSocketChannelFactory(asyncExec, asyncExec, 1);
- myPipelineFactory = new ChannelPipelineFactory() {
- public ChannelPipeline getPipeline() throws Exception {
- return Channels.pipeline(
- new ProtobufVarint32FrameDecoder(),
- new ProtobufDecoder(msgDefaultInstance),
- new ProtobufVarint32LengthFieldPrepender(),
- new ProtobufEncoder(),
- myMessageHandler
- );
+ myEventLoopGroup = new NioEventLoopGroup(1, asyncExec);
+ myChannelInitializer = new ChannelInitializer() {
+ @Override
+ protected void initChannel(Channel channel) throws Exception {
+ channel.pipeline().addLast(new ProtobufVarint32FrameDecoder(),
+ new ProtobufDecoder(msgDefaultInstance),
+ new ProtobufVarint32LengthFieldPrepender(),
+ new ProtobufEncoder(),
+ myMessageHandler);
}
};
}
@@ -76,15 +75,10 @@
boolean success = false;
try {
- final ClientBootstrap bootstrap = new ClientBootstrap(myChannelFactory);
- bootstrap.setPipelineFactory(myPipelineFactory);
- bootstrap.setOption("tcpNoDelay", true);
- bootstrap.setOption("keepAlive", true);
- final ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
- future.awaitUninterruptibly();
-
+ final Bootstrap bootstrap = new Bootstrap().group(myEventLoopGroup).channel(NioSocketChannel.class).handler(myChannelInitializer);
+ bootstrap.option(ChannelOption.TCP_NODELAY, true).option(ChannelOption.SO_KEEPALIVE, true);
+ final ChannelFuture future = bootstrap.connect(host, port).syncUninterruptibly();
success = future.isSuccess();
-
if (success) {
myConnectFuture = future;
try {
@@ -94,13 +88,6 @@
LOG.error(e);
}
}
- else {
- final Throwable reason = future.getCause();
- if (reason != null) {
- throw reason;
- }
- }
-
return success;
}
finally {
@@ -129,7 +116,7 @@
catch (Throwable e) {
LOG.error(e);
}
- final ChannelFuture closeFuture = future.getChannel().close();
+ final ChannelFuture closeFuture = future.channel().close();
closeFuture.awaitUninterruptibly();
}
}
@@ -154,9 +141,10 @@
final RequestFuture<T> requestFuture = new RequestFuture<T>(responseHandler, messageId, cancelAction);
myMessageHandler.registerFuture(messageId, requestFuture);
final ChannelFuture connectFuture = myConnectFuture;
- final Channel channel = connectFuture != null? connectFuture.getChannel() : null;
- if (channel != null && channel.isConnected()) {
- Channels.write(channel, message).addListener(new ChannelFutureListener() {
+ final Channel channel = connectFuture != null? connectFuture.channel() : null;
+ if (channel != null && channel.isActive()) {
+ channel.writeAndFlush(message).addListener(new ChannelFutureListener() {
+ @Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {
notifyTerminated(messageId, requestFuture, responseHandler);
diff --git a/jps/jps-builders/src/org/jetbrains/jps/client/UUIDGetter.java b/jps/jps-builders/src/org/jetbrains/jps/client/UUIDGetter.java
index 675a629..cba6db4 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/client/UUIDGetter.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/client/UUIDGetter.java
@@ -15,8 +15,8 @@
*/
package org.jetbrains.jps.client;
-import org.jboss.netty.channel.MessageEvent;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.javac.JavacRemoteProto;
import java.util.UUID;
@@ -25,5 +25,5 @@
* Date: 1/22/12
*/
public interface UUIDGetter {
- @NotNull UUID getSessionUUID(@NotNull MessageEvent e);
+ @NotNull UUID getSessionUUID(@NotNull JavacRemoteProto.Message message);
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java
index 0bc2107..0e47e0c 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java
@@ -18,16 +18,17 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.*;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.codec.protobuf.ProtobufDecoder;
+import io.netty.handler.codec.protobuf.ProtobufEncoder;
+import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
+import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.xml.DOMConfigurator;
-import org.jboss.netty.bootstrap.ClientBootstrap;
-import org.jboss.netty.channel.*;
-import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
-import org.jboss.netty.handler.codec.protobuf.ProtobufDecoder;
-import org.jboss.netty.handler.codec.protobuf.ProtobufEncoder;
-import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
-import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -45,6 +46,7 @@
* @author Eugene Zhuravlev
* Date: 4/16/12
*/
+@SuppressWarnings("UseOfSystemOutOrSystemErr")
public class BuildMain {
private static final String LOG_CONFIG_FILE_NAME = "build-log.xml";
private static final String LOG_FILE_NAME = "build.log";
@@ -56,42 +58,37 @@
LOG = Logger.getInstance("#org.jetbrains.jps.cmdline.BuildMain");
}
- private static NioClientSocketChannelFactory ourChannelFactory;
+ private static NioEventLoopGroup ourEventLoopGroup;
public static void main(String[] args){
System.out.println("Build process started. Classpath: " + System.getProperty("java.class.path"));
final String host = args[0];
final int port = Integer.parseInt(args[1]);
final UUID sessionId = UUID.fromString(args[2]);
+ @SuppressWarnings("ConstantConditions")
final File systemDir = new File(FileUtil.toCanonicalPath(args[3]));
Utils.setSystemRoot(systemDir);
- ourChannelFactory = new NioClientSocketChannelFactory(SharedThreadPool.getInstance(), SharedThreadPool.getInstance(), 1);
- final ClientBootstrap bootstrap = new ClientBootstrap(ourChannelFactory);
- bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
- public ChannelPipeline getPipeline() throws Exception {
- return Channels.pipeline(
- new ProtobufVarint32FrameDecoder(),
- new ProtobufDecoder(CmdlineRemoteProto.Message.getDefaultInstance()),
- new ProtobufVarint32LengthFieldPrepender(),
- new ProtobufEncoder(),
- new MyMessageHandler(sessionId)
- );
+ ourEventLoopGroup = new NioEventLoopGroup(1, SharedThreadPool.getInstance());
+ final Bootstrap bootstrap = new Bootstrap().group(ourEventLoopGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer() {
+ @Override
+ protected void initChannel(Channel channel) throws Exception {
+ channel.pipeline().addLast(new ProtobufVarint32FrameDecoder(),
+ new ProtobufDecoder(CmdlineRemoteProto.Message.getDefaultInstance()),
+ new ProtobufVarint32LengthFieldPrepender(),
+ new ProtobufEncoder(),
+ new MyMessageHandler(sessionId));
}
- });
- bootstrap.setOption("tcpNoDelay", true);
- bootstrap.setOption("keepAlive", true);
+ }).option(ChannelOption.TCP_NODELAY, true).option(ChannelOption.SO_KEEPALIVE, true);
- final ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
- future.awaitUninterruptibly();
-
+ final ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port)).awaitUninterruptibly();
final boolean success = future.isSuccess();
-
if (success) {
- Channels.write(future.getChannel(), CmdlineProtoUtil.toMessage(sessionId, CmdlineProtoUtil.createParamRequest()));
+ future.channel().writeAndFlush(CmdlineProtoUtil.toMessage(sessionId, CmdlineProtoUtil.createParamRequest()));
}
else {
- final Throwable reason = future.getCause();
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ final Throwable reason = future.cause();
System.err.println("Error connecting to " + host + ":" + port + "; reason: " + (reason != null? reason.getMessage() : "unknown"));
if (reason != null) {
reason.printStackTrace(System.err);
@@ -101,7 +98,7 @@
}
}
- private static class MyMessageHandler extends SimpleChannelHandler {
+ private static class MyMessageHandler extends SimpleChannelInboundHandler<CmdlineRemoteProto.Message> {
private final UUID mySessionId;
private volatile BuildSession mySession;
@@ -110,10 +107,9 @@
}
@Override
- public void messageReceived(final ChannelHandlerContext ctx, MessageEvent e) throws Exception {
- CmdlineRemoteProto.Message message = (CmdlineRemoteProto.Message)e.getMessage();
+ public void channelRead0(final ChannelHandlerContext context, CmdlineRemoteProto.Message message) throws Exception {
final CmdlineRemoteProto.Message.Type type = message.getType();
- final Channel channel = ctx.getChannel();
+ final Channel channel = context.channel();
if (type == CmdlineRemoteProto.Message.Type.CONTROLLER_MESSAGE) {
final CmdlineRemoteProto.Message.ControllerMessage controllerMessage = message.getControllerMessage();
@@ -125,7 +121,9 @@
final BuildSession session = new BuildSession(mySessionId, channel, controllerMessage.getParamsMessage(), delta);
mySession = session;
SharedThreadPool.getInstance().executeOnPooledThread(new Runnable() {
+ @Override
public void run() {
+ //noinspection finally
try {
session.run();
}
@@ -172,19 +170,22 @@
}
}
- Channels.write(channel, CmdlineProtoUtil.toMessage(mySessionId, CmdlineProtoUtil.createFailure("Unsupported message type: " + type.name(), null)));
+ channel.writeAndFlush(
+ CmdlineProtoUtil.toMessage(mySessionId, CmdlineProtoUtil.createFailure("Unsupported message type: " + type.name(), null)));
}
@Override
- public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+ public void channelInactive(ChannelHandlerContext context) throws Exception {
try {
- super.channelClosed(ctx, e);
+ super.channelInactive(context);
}
finally {
new Thread("Shutdown thread") {
+ @Override
public void run() {
+ //noinspection finally
try {
- ourChannelFactory.releaseExternalResources();
+ ourEventLoopGroup.shutdownGracefully();
}
finally {
System.exit(0);
@@ -193,16 +194,6 @@
}.start();
}
}
-
- @Override
- public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
- try {
- super.channelDisconnected(ctx, e);
- }
- finally {
- ctx.getChannel().close();
- }
- }
}
private static void initLoggers() {
@@ -217,6 +208,7 @@
}
catch (IOException e) {
System.err.println("Failed to configure logging: ");
+ //noinspection UseOfSystemOutOrSystemErr
e.printStackTrace(System.err);
}
@@ -278,6 +270,7 @@
private static void ensureLogConfigExists(final File logConfig) throws IOException {
if (!logConfig.exists()) {
FileUtil.createIfDoesntExist(logConfig);
+ @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
final InputStream in = BuildMain.class.getResourceAsStream("/" + DEFAULT_LOGGER_CONFIG);
if (in != null) {
try {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java
index b841e32..f6d27c8 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java
@@ -24,16 +24,15 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.concurrency.SequentialTaskExecutor;
import com.intellij.util.io.DataOutputStream;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.Channels;
+import io.netty.channel.Channel;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.TimingLog;
import org.jetbrains.jps.api.*;
import org.jetbrains.jps.builders.*;
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
import org.jetbrains.jps.builders.java.dependencyView.Callbacks;
import org.jetbrains.jps.incremental.MessageHandler;
import org.jetbrains.jps.incremental.TargetTypeRegistry;
-import org.jetbrains.jps.TimingLog;
import org.jetbrains.jps.incremental.Utils;
import org.jetbrains.jps.incremental.fs.BuildFSState;
import org.jetbrains.jps.incremental.fs.FSState;
@@ -99,6 +98,7 @@
myBuildRunner = new BuildRunner(loader, filePaths, builderParams);
}
+ @Override
public void run() {
Throwable error = null;
final Ref<Boolean> hasErrors = new Ref<Boolean>(false);
@@ -111,6 +111,7 @@
}
runBuild(new MessageHandler() {
+ @Override
public void processMessage(BuildMessage buildMessage) {
final CmdlineRemoteProto.Message.BuilderMessage response;
if (buildMessage instanceof FileGeneratedEvent) {
@@ -151,7 +152,7 @@
response = null;
}
if (response != null) {
- Channels.write(myChannel, CmdlineProtoUtil.toMessage(mySessionId, response));
+ myChannel.writeAndFlush(CmdlineProtoUtil.toMessage(mySessionId, response));
}
}
}, this);
@@ -441,9 +442,10 @@
private static void saveOnDisk(BufferExposingByteArrayOutputStream bytes, final File file) throws IOException {
FileOutputStream fos = null;
try {
+ //noinspection IOResourceOpenedButNotSafelyClosed
fos = new FileOutputStream(file);
}
- catch (FileNotFoundException e) {
+ catch (FileNotFoundException ignored) {
FileUtil.createIfDoesntExist(file);
}
@@ -541,7 +543,7 @@
}
finally {
try {
- Channels.write(myChannel, lastMessage).await();
+ myChannel.writeAndFlush(lastMessage).await();
}
catch (InterruptedException e) {
LOG.info(e);
@@ -607,11 +609,8 @@
if (prev != null) {
prev.setDone();
}
- Channels.write(myChannel,
- CmdlineProtoUtil.toMessage(
- mySessionId, CmdlineRemoteProto.Message.BuilderMessage.newBuilder().setType(CmdlineRemoteProto.Message.BuilderMessage.Type.CONSTANT_SEARCH_TASK).setConstantSearchTask(task.build()).build()
- )
- );
+ myChannel.writeAndFlush(CmdlineProtoUtil.toMessage(mySessionId, CmdlineRemoteProto.Message.BuilderMessage.newBuilder()
+ .setType(CmdlineRemoteProto.Message.BuilderMessage.Type.CONSTANT_SEARCH_TASK).setConstantSearchTask(task.build()).build()));
return future;
}
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java
index 6b9fef1..ecf2ba0 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java
@@ -26,8 +26,8 @@
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ContainerUtil;
import com.jgoodies.forms.layout.CellConstraints;
+import io.netty.util.NetUtil;
import net.n3.nanoxml.IXMLBuilder;
-import org.jboss.netty.util.Version;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.ClassVisitor;
import org.jetbrains.asm4.ClassWriter;
@@ -57,7 +57,7 @@
@SuppressWarnings("unchecked") Class<StandardJavaFileManager> c = (Class<StandardJavaFileManager>)Class.forName(CLASS_NAME);
aClass = c;
}
- catch (Throwable e) {
+ catch (Throwable ignored) {
aClass = null;
}
managerClass = aClass;
@@ -76,7 +76,7 @@
@SuppressWarnings("unchecked") Class<StandardJavaFileManager> c = (Class<StandardJavaFileManager>)Class.forName(CLASS_NAME);
aClass = c;
}
- catch (Throwable e) {
+ catch (Throwable ignored) {
aClass = null;
}
managerClass = aClass;
@@ -96,7 +96,7 @@
cp.addAll(PathManager.getUtilClassPath()); // util
cp.add(getResourcePath(Message.class)); // protobuf
- cp.add(getResourcePath(Version.class)); // netty
+ cp.add(getResourcePath(NetUtil.class)); // netty
cp.add(getResourcePath(ClassWriter.class)); // asm
cp.add(getResourcePath(ClassVisitor.class)); // asm-commons
cp.add(getResourcePath(JpsModel.class)); // jps-model-api
@@ -141,7 +141,7 @@
cp.add(getResourceFile(JpsModel.class)); // jps-model-api
cp.add(getResourceFile(JpsModelImpl.class)); // jps-model-impl
cp.add(getResourceFile(Message.class)); // protobuf
- cp.add(getResourceFile(Version.class)); // netty
+ cp.add(getResourceFile(NetUtil.class)); // netty
final Class<StandardJavaFileManager> optimizedFileManagerClass = getOptimizedFileManagerClass();
if (optimizedFileManagerClass != null) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java
index 76a6fe9..b901f95 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java
@@ -15,74 +15,60 @@
*/
package org.jetbrains.jps.javac;
-import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.*;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.channel.group.ChannelGroupFuture;
-import org.jboss.netty.channel.group.DefaultChannelGroup;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
-import org.jboss.netty.handler.codec.protobuf.ProtobufDecoder;
-import org.jboss.netty.handler.codec.protobuf.ProtobufEncoder;
-import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
-import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.*;
+import io.netty.channel.group.ChannelGroup;
+import io.netty.channel.group.ChannelGroupFuture;
+import io.netty.channel.group.DefaultChannelGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.codec.protobuf.ProtobufDecoder;
+import io.netty.handler.codec.protobuf.ProtobufEncoder;
+import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
+import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
+import io.netty.util.concurrent.ImmediateEventExecutor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.api.CanceledStatus;
import org.jetbrains.jps.service.SharedThreadPool;
import javax.tools.*;
import java.io.File;
-import java.net.InetSocketAddress;
import java.util.*;
/**
* @author Eugene Zhuravlev
* Date: 1/22/12
*/
+@SuppressWarnings("UseOfSystemOutOrSystemErr")
public class JavacServer {
public static final int DEFAULT_SERVER_PORT = 7878;
public static final String SERVER_SUCCESS_START_MESSAGE = "Javac server started successfully. Listening on port: ";
public static final String SERVER_ERROR_START_MESSAGE = "Error starting Javac Server: ";
public static final String USE_ECLIPSE_COMPILER_PROPERTY = "use.eclipse.compiler";
- private final ChannelGroup myAllOpenChannels = new DefaultChannelGroup("javac-server");
- private final ChannelFactory myChannelFactory;
- private final ChannelPipelineFactory myPipelineFactory;
-
- public JavacServer() {
- myChannelFactory = new NioServerSocketChannelFactory(SharedThreadPool.getInstance(), SharedThreadPool.getInstance(), 1);
- final ChannelRegistrar channelRegistrar = new ChannelRegistrar();
- final ChannelHandler compilationRequestsHandler = new CompilationRequestsHandler();
- myPipelineFactory = new ChannelPipelineFactory() {
- public ChannelPipeline getPipeline() throws Exception {
- return Channels.pipeline(
- channelRegistrar,
- new ProtobufVarint32FrameDecoder(),
- new ProtobufDecoder(JavacRemoteProto.Message.getDefaultInstance()),
- new ProtobufVarint32LengthFieldPrepender(),
- new ProtobufEncoder(),
- compilationRequestsHandler
- );
- }
- };
- }
+ private ChannelRegistrar myChannelRegistrar;
public void start(int listenPort) {
- final ServerBootstrap bootstrap = new ServerBootstrap(myChannelFactory);
- bootstrap.setPipelineFactory(myPipelineFactory);
- bootstrap.setOption("child.tcpNoDelay", true);
- bootstrap.setOption("child.keepAlive", true);
- final Channel serverChannel = bootstrap.bind(new InetSocketAddress(listenPort));
- myAllOpenChannels.add(serverChannel);
+ final ServerBootstrap bootstrap = new ServerBootstrap().group(new NioEventLoopGroup(1, SharedThreadPool.getInstance())).channel(NioServerSocketChannel.class);
+ bootstrap.childOption(ChannelOption.TCP_NODELAY, true).childOption(ChannelOption.SO_KEEPALIVE, true);
+ myChannelRegistrar = new ChannelRegistrar();
+ final ChannelHandler compilationRequestsHandler = new CompilationRequestsHandler();
+ bootstrap.childHandler(new ChannelInitializer() {
+ @Override
+ protected void initChannel(Channel channel) throws Exception {
+ channel.pipeline().addLast(myChannelRegistrar,
+ new ProtobufVarint32FrameDecoder(),
+ new ProtobufDecoder(JavacRemoteProto.Message.getDefaultInstance()),
+ new ProtobufVarint32LengthFieldPrepender(),
+ new ProtobufEncoder(),
+ compilationRequestsHandler);
+ }
+ });
+ myChannelRegistrar.add(bootstrap.bind(listenPort).syncUninterruptibly().channel());
}
public void stop() {
- try {
- final ChannelGroupFuture closeFuture = myAllOpenChannels.close();
- closeFuture.awaitUninterruptibly();
- }
- finally {
- myChannelFactory.releaseExternalResources();
- }
+ myChannelRegistrar.close().awaitUninterruptibly();
}
public static void main(String[] args) {
@@ -101,6 +87,7 @@
final JavacServer server = new JavacServer();
server.start(port);
Runtime.getRuntime().addShutdownHook(new Thread("Shutdown hook thread") {
+ @Override
public void run() {
server.stop();
}
@@ -116,8 +103,7 @@
}
}
-
- public static JavacRemoteProto.Message compile(final ChannelHandlerContext ctx,
+ public static JavacRemoteProto.Message compile(final ChannelHandlerContext context,
final UUID sessionId,
List<String> options,
Collection<File> files,
@@ -129,28 +115,31 @@
final DiagnosticOutputConsumer diagnostic = new DiagnosticOutputConsumer() {
@Override
public void javaFileLoaded(File file) {
- Channels.write(ctx.getChannel(), JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createSourceFileLoadedResponse(file)));
+ context.channel().writeAndFlush(JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createSourceFileLoadedResponse(file)));
}
+ @Override
public void outputLineAvailable(String line) {
- Channels.write(ctx.getChannel(), JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createStdOutputResponse(line)));
+ context.channel().writeAndFlush(JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createStdOutputResponse(line)));
}
+ @Override
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
final JavacRemoteProto.Message.Response response = JavacProtoUtil.createBuildMessageResponse(diagnostic);
- Channels.write(ctx.getChannel(), JavacProtoUtil.toMessage(sessionId, response));
+ context.channel().writeAndFlush(JavacProtoUtil.toMessage(sessionId, response));
}
@Override
public void registerImports(String className, Collection<String> imports, Collection<String> staticImports) {
final JavacRemoteProto.Message.Response response = JavacProtoUtil.createClassDataResponse(className, imports, staticImports);
- Channels.write(ctx.getChannel(), JavacProtoUtil.toMessage(sessionId, response));
+ context.channel().writeAndFlush(JavacProtoUtil.toMessage(sessionId, response));
}
};
final OutputFileConsumer outputSink = new OutputFileConsumer() {
+ @Override
public void save(@NotNull OutputFileObject fileObject) {
- Channels.write(ctx.getChannel(), JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createOutputObjectResponse(fileObject)));
+ context.channel().writeAndFlush(JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createOutputObjectResponse(fileObject)));
}
};
@@ -159,6 +148,7 @@
return JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createBuildCompletedResponse(rc));
}
catch (Throwable e) {
+ //noinspection UseOfSystemOutOrSystemErr
e.printStackTrace(System.err);
return JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createFailure(e.getMessage(), e));
}
@@ -182,18 +172,18 @@
return files;
}
- private class CompilationRequestsHandler extends SimpleChannelHandler {
-
- public void messageReceived(final ChannelHandlerContext ctx, MessageEvent e) throws Exception {
- final JavacRemoteProto.Message msg = (JavacRemoteProto.Message)e.getMessage();
- final UUID sessionId = JavacProtoUtil.fromProtoUUID(msg.getSessionId());
- final JavacRemoteProto.Message.Type messageType = msg.getMessageType();
+ @ChannelHandler.Sharable
+ private class CompilationRequestsHandler extends SimpleChannelInboundHandler<JavacRemoteProto.Message> {
+ @Override
+ public void channelRead0(final ChannelHandlerContext context, JavacRemoteProto.Message message) throws Exception {
+ final UUID sessionId = JavacProtoUtil.fromProtoUUID(message.getSessionId());
+ final JavacRemoteProto.Message.Type messageType = message.getMessageType();
JavacRemoteProto.Message reply = null;
try {
if (messageType == JavacRemoteProto.Message.Type.REQUEST) {
- final JavacRemoteProto.Message.Request request = msg.getRequest();
+ final JavacRemoteProto.Message.Request request = message.getRequest();
final JavacRemoteProto.Message.Request.Type requestType = request.getRequestType();
if (requestType == JavacRemoteProto.Message.Request.Type.COMPILE) {
final List<String> options = request.getOptionList();
@@ -214,11 +204,11 @@
final CancelHandler cancelHandler = new CancelHandler();
myCancelHandlers.add(cancelHandler);
SharedThreadPool.getInstance().executeOnPooledThread(new Runnable() {
+ @Override
public void run() {
try {
- final JavacRemoteProto.Message exitMsg =
- compile(ctx, sessionId, options, files, cp, platformCp, srcPath, outs, cancelHandler);
- Channels.write(ctx.getChannel(), exitMsg);
+ context.channel()
+ .writeAndFlush(compile(context, sessionId, options, files, cp, platformCp, srcPath, outs, cancelHandler));
}
finally {
myCancelHandlers.remove(cancelHandler);
@@ -233,7 +223,9 @@
else if (requestType == JavacRemoteProto.Message.Request.Type.SHUTDOWN){
cancelBuilds();
new Thread("StopThread") {
+ @Override
public void run() {
+ //noinspection finally
try {
JavacServer.this.stop();
}
@@ -253,20 +245,51 @@
}
finally {
if (reply != null) {
- Channels.write(ctx.getChannel(), reply);
+ context.channel().writeAndFlush(reply);
}
}
}
-
- public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
- super.exceptionCaught(ctx, e);
- }
}
- private class ChannelRegistrar extends SimpleChannelUpstreamHandler {
- public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
- myAllOpenChannels.add(e.getChannel());
- super.channelOpen(ctx, e);
+ @ChannelHandler.Sharable
+ private static final class ChannelRegistrar extends ChannelInboundHandlerAdapter {
+ private final ChannelGroup openChannels = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE);
+
+ public boolean isEmpty() {
+ return openChannels.isEmpty();
+ }
+
+ public void add(@NotNull Channel serverChannel) {
+ assert serverChannel instanceof ServerChannel;
+ openChannels.add(serverChannel);
+ }
+
+ @Override
+ public void channelActive(ChannelHandlerContext context) throws Exception {
+ // we don't need to remove channel on close - ChannelGroup do it
+ openChannels.add(context.channel());
+
+ super.channelActive(context);
+ }
+
+ public ChannelGroupFuture close() {
+ EventLoopGroup eventLoopGroup = null;
+ for (Channel channel : openChannels) {
+ if (channel instanceof ServerChannel) {
+ eventLoopGroup = channel.eventLoop().parent();
+ break;
+ }
+ }
+
+ ChannelGroupFuture future;
+ try {
+ future = openChannels.close();
+ }
+ finally {
+ assert eventLoopGroup != null;
+ eventLoopGroup.shutdownGracefully();
+ }
+ return future;
}
}
@@ -280,6 +303,7 @@
myIsCanceled = true;
}
+ @Override
public boolean isCanceled() {
return myIsCanceled;
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerClient.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerClient.java
index d9103ed..bb553a9 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerClient.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerClient.java
@@ -15,7 +15,6 @@
*/
package org.jetbrains.jps.javac;
-import org.jboss.netty.channel.MessageEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.api.RequestFuture;
import org.jetbrains.jps.client.SimpleProtobufClient;
@@ -33,9 +32,9 @@
public JavacServerClient() {
super(JavacRemoteProto.Message.getDefaultInstance(), SharedThreadPool.getInstance(), new UUIDGetter() {
+ @Override
@NotNull
- public UUID getSessionUUID(@NotNull MessageEvent e) {
- final JavacRemoteProto.Message message = (JavacRemoteProto.Message)e.getMessage();
+ public UUID getSessionUUID(@NotNull JavacRemoteProto.Message message) {
final JavacRemoteProto.Message.UUID uuid = message.getSessionId();
return new UUID(uuid.getMostSigBits(), uuid.getLeastSigBits());
}
@@ -46,6 +45,7 @@
final JavacServerResponseHandler rh = new JavacServerResponseHandler(diagnosticSink, outputSink);
final JavacRemoteProto.Message.Request request = JavacProtoUtil.createCompilationRequest(options, files, classpath, platformCp, sourcePath, outs);
return sendRequest(request, rh, new RequestFuture.CancelAction<JavacServerResponseHandler>() {
+ @Override
public void cancel(RequestFuture<JavacServerResponseHandler> javacServerResponseHandlerRequestFuture) throws Exception {
sendRequest(JavacProtoUtil.createCancelRequest(), null, null);
}
diff --git a/lib/netty-3.6.6.Final.jar b/lib/netty-3.6.6.Final.jar
deleted file mode 100644
index 35cb073..0000000
--- a/lib/netty-3.6.6.Final.jar
+++ /dev/null
Binary files differ
diff --git a/lib/netty-all.jar b/lib/netty-all.jar
new file mode 100644
index 0000000..847efe5
--- /dev/null
+++ b/lib/netty-all.jar
Binary files differ
diff --git a/lib/required_for_dist.txt b/lib/required_for_dist.txt
index 5e07e02..6f98799 100644
--- a/lib/required_for_dist.txt
+++ b/lib/required_for_dist.txt
@@ -47,7 +47,7 @@
xpp3-1.1.4-min.jar
xstream-1.4.3.jar
swingx-core-1.6.2.jar
-netty-3.6.6.Final.jar
+netty-all.jar
protobuf-2.5.0.jar
rhino-js-1_7R4.jar
proxy-vole_20120920.jar
diff --git a/lib/src/netty-3.6.6.Final-sources.jar b/lib/src/netty-3.6.6.Final-sources.jar
deleted file mode 100644
index 4144cf5..0000000
--- a/lib/src/netty-3.6.6.Final-sources.jar
+++ /dev/null
Binary files differ
diff --git a/lib/src/netty-all-sources.jar b/lib/src/netty-all-sources.jar
new file mode 100644
index 0000000..07ac406
--- /dev/null
+++ b/lib/src/netty-all-sources.jar
Binary files differ
diff --git a/platform/analysis-api/src/com/intellij/packageDependencies/DependencyRule.java b/platform/analysis-api/src/com/intellij/packageDependencies/DependencyRule.java
index fb2fdd0..99acb49 100644
--- a/platform/analysis-api/src/com/intellij/packageDependencies/DependencyRule.java
+++ b/platform/analysis-api/src/com/intellij/packageDependencies/DependencyRule.java
@@ -21,6 +21,7 @@
import com.intellij.psi.search.scope.packageSet.ComplementPackageSet;
import com.intellij.psi.search.scope.packageSet.NamedScope;
import com.intellij.psi.search.scope.packageSet.PackageSet;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class DependencyRule {
@@ -34,7 +35,7 @@
myDenyRule = isDenyRule;
}
- public boolean isForbiddenToUse(PsiFile from, PsiFile to) {
+ public boolean isForbiddenToUse(@NotNull PsiFile from, @NotNull PsiFile to) {
if (myFromScope == null || myToScope == null) return false;
final PackageSet fromSet = myFromScope.getValue();
final PackageSet toSet = myToScope.getValue();
@@ -46,7 +47,7 @@
&& toSet.contains(to, holder);
}
- public boolean isApplicable(PsiFile file){
+ public boolean isApplicable(@NotNull PsiFile file){
if (myFromScope == null || myToScope == null) return false;
final PackageSet fromSet = myFromScope.getValue();
if (fromSet == null) return false;
diff --git a/platform/analysis-api/src/com/intellij/packageDependencies/DependencyValidationManager.java b/platform/analysis-api/src/com/intellij/packageDependencies/DependencyValidationManager.java
index d1818b3..723aef8 100644
--- a/platform/analysis-api/src/com/intellij/packageDependencies/DependencyValidationManager.java
+++ b/platform/analysis-api/src/com/intellij/packageDependencies/DependencyValidationManager.java
@@ -41,24 +41,26 @@
public abstract boolean hasRules();
@Nullable
- public abstract DependencyRule getViolatorDependencyRule(PsiFile from, PsiFile to);
+ public abstract DependencyRule getViolatorDependencyRule(@NotNull PsiFile from, @NotNull PsiFile to);
@NotNull
- public abstract DependencyRule[] getViolatorDependencyRules(PsiFile from, PsiFile to);
+ public abstract DependencyRule[] getViolatorDependencyRules(@NotNull PsiFile from, @NotNull PsiFile to);
@NotNull
- public abstract DependencyRule[] getApplicableRules(PsiFile file);
+ public abstract DependencyRule[] getApplicableRules(@NotNull PsiFile file);
+ @NotNull
public abstract DependencyRule[] getAllRules();
public abstract void removeAllRules();
- public abstract void addRule(DependencyRule rule);
+ public abstract void addRule(@NotNull DependencyRule rule);
public abstract boolean skipImportStatements();
public abstract void setSkipImportStatements(boolean skip);
+ @NotNull
public abstract Map<String,PackageSet> getUnnamedScopes();
public abstract void reloadRules();
diff --git a/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/NamedScopesHolder.java b/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/NamedScopesHolder.java
index 58e66d9..61bd320 100644
--- a/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/NamedScopesHolder.java
+++ b/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/NamedScopesHolder.java
@@ -156,9 +156,9 @@
@Override
public void loadState(final Element state) {
myScopes.clear();
- List sets = state.getChildren(SCOPE_TAG);
- for (Object set : sets) {
- addScope(readScope((Element)set));
+ List<Element> sets = state.getChildren(SCOPE_TAG);
+ for (Element set : sets) {
+ myScopes.add(readScope(set));
}
fireScopeListeners();
}
diff --git a/platform/analysis-impl/src/com/intellij/packageDependencies/DependencyValidationManagerImpl.java b/platform/analysis-impl/src/com/intellij/packageDependencies/DependencyValidationManagerImpl.java
index 190aaca..85215739 100644
--- a/platform/analysis-impl/src/com/intellij/packageDependencies/DependencyValidationManagerImpl.java
+++ b/platform/analysis-impl/src/com/intellij/packageDependencies/DependencyValidationManagerImpl.java
@@ -25,7 +25,9 @@
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.scope.packageSet.*;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.UniqueNameGenerator;
+import com.intellij.util.ui.UIUtil;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -46,6 +48,7 @@
private static final Logger LOG = Logger.getInstance("#com.intellij.packageDependencies.DependencyValidationManagerImpl");
private final List<DependencyRule> myRules = new ArrayList<DependencyRule>();
+ private final NamedScopeManager myNamedScopeManager;
public boolean SKIP_IMPORT_STATEMENTS = false;
@@ -59,8 +62,15 @@
private final Map<String, PackageSet> myUnnamedScopes = new HashMap<String, PackageSet>();
- public DependencyValidationManagerImpl(final Project project) {
+ public DependencyValidationManagerImpl(final Project project, NamedScopeManager namedScopeManager) {
super(project);
+ myNamedScopeManager = namedScopeManager;
+ namedScopeManager.addScopeListener(new ScopeListener() {
+ @Override
+ public void scopesChanged() {
+ reloadScopes();
+ }
+ });
}
@Override
@@ -95,7 +105,7 @@
@Override
@Nullable
- public DependencyRule getViolatorDependencyRule(PsiFile from, PsiFile to) {
+ public DependencyRule getViolatorDependencyRule(@NotNull PsiFile from, @NotNull PsiFile to) {
for (DependencyRule dependencyRule : myRules) {
if (dependencyRule.isForbiddenToUse(from, to)) return dependencyRule;
}
@@ -105,7 +115,7 @@
@Override
@NotNull
- public DependencyRule[] getViolatorDependencyRules(PsiFile from, PsiFile to) {
+ public DependencyRule[] getViolatorDependencyRules(@NotNull PsiFile from, @NotNull PsiFile to) {
ArrayList<DependencyRule> result = new ArrayList<DependencyRule>();
for (DependencyRule dependencyRule : myRules) {
if (dependencyRule.isForbiddenToUse(from, to)) {
@@ -117,7 +127,7 @@
@NotNull
@Override
- public DependencyRule[] getApplicableRules(PsiFile file) {
+ public DependencyRule[] getApplicableRules(@NotNull PsiFile file) {
ArrayList<DependencyRule> result = new ArrayList<DependencyRule>();
for (DependencyRule dependencyRule : myRules) {
if (dependencyRule.isApplicable(file)) {
@@ -137,11 +147,13 @@
SKIP_IMPORT_STATEMENTS = skip;
}
+ @NotNull
@Override
public Map<String, PackageSet> getUnnamedScopes() {
return myUnnamedScopes;
}
+ @NotNull
@Override
public DependencyRule[] getAllRules() {
return myRules.toArray(new DependencyRule[myRules.size()]);
@@ -153,7 +165,7 @@
}
@Override
- public void addRule(DependencyRule rule) {
+ public void addRule(@NotNull DependencyRule rule) {
appendUnnamedScope(rule.getFromScope());
appendUnnamedScope(rule.getToScope());
myRules.add(rule);
@@ -193,8 +205,8 @@
catch (InvalidDataException e) {
LOG.info(e);
}
- super.loadState(element);
+ super.loadState(element);
myUnnamedScopes.clear();
final List unnamedScopes = element.getChildren(UNNAMED_SCOPE);
final PackageSetFactory packageSetFactory = PackageSetFactory.getInstance();
@@ -212,7 +224,8 @@
}
private void readRules(Element element) {
- myRules.clear();
+ removeAllRules();
+
List rules = element.getChildren(DENY_RULE_KEY);
for (Object rule1 : rules) {
DependencyRule rule = readRule((Element)rule1);
@@ -336,4 +349,40 @@
}
}
+
+ private final List<Pair<NamedScope, NamedScopesHolder>> myScopes = ContainerUtil.createLockFreeCopyOnWriteList();
+
+ private void reloadScopes() {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ if (getProject().isDisposed()) return;
+ List<Pair<NamedScope, NamedScopesHolder>> scopeList = new ArrayList<Pair<NamedScope, NamedScopesHolder>>();
+ addScopesToList(scopeList, DependencyValidationManagerImpl.this);
+ addScopesToList(scopeList, myNamedScopeManager);
+ myScopes.clear();
+ myScopes.addAll(scopeList);
+ reloadRules();
+ }
+ });
+ }
+
+ private static void addScopesToList(@NotNull final List<Pair<NamedScope, NamedScopesHolder>> scopeList,
+ @NotNull final NamedScopesHolder holder) {
+ NamedScope[] scopes = holder.getScopes();
+ for (NamedScope scope : scopes) {
+ scopeList.add(Pair.create(scope, holder));
+ }
+ }
+
+ @NotNull
+ public List<Pair<NamedScope, NamedScopesHolder>> getScopeBasedHighlightingCachedScopes() {
+ return myScopes;
+ }
+
+ @Override
+ public void fireScopeListeners() {
+ super.fireScopeListeners();
+ reloadScopes();
+ }
}
diff --git a/platform/annotations/annotations.iml b/platform/annotations/annotations.iml
index c053808..262fa56 100644
--- a/platform/annotations/annotations.iml
+++ b/platform/annotations/annotations.iml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<module relativePaths="true" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
diff --git a/platform/platform-api/src/com/intellij/openapi/application/WriteAction.java b/platform/core-api/src/com/intellij/openapi/application/WriteAction.java
similarity index 71%
rename from platform/platform-api/src/com/intellij/openapi/application/WriteAction.java
rename to platform/core-api/src/com/intellij/openapi/application/WriteAction.java
index 4396c2b..b8c5e16 100644
--- a/platform/platform-api/src/com/intellij/openapi/application/WriteAction.java
+++ b/platform/core-api/src/com/intellij/openapi/application/WriteAction.java
@@ -16,10 +16,11 @@
package com.intellij.openapi.application;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.ui.GuiUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
+
public abstract class WriteAction<T> extends BaseActionRunnable<T> {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.application.WriteAction");
@NotNull
@@ -27,27 +28,36 @@
public RunResult<T> execute() {
final RunResult<T> result = new RunResult<T>(this);
- if (canWriteNow()) {
+ final Application application = ApplicationManager.getApplication();
+ if (application.isWriteAccessAllowed()) {
result.run();
return result;
}
try {
- if (!ApplicationManager.getApplication().isDispatchThread() && ApplicationManager.getApplication().isReadAccessAllowed()) {
+ if (!application.isDispatchThread() && application.isReadAccessAllowed()) {
LOG.error("Must not start write action from within read action in the other thread - deadlock is coming");
}
- GuiUtils.runOrInvokeAndWait(new Runnable() {
+ Runnable runnable = new Runnable() {
@Override
public void run() {
- final AccessToken accessToken = start();
- try {
- result.run();
- }
- finally {
- accessToken.finish();
- }
+ application.runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ result.run();
+ }
+ });
}
- });
+ };
+ if (application.isDispatchThread()) {
+ runnable.run();
+ }
+ else if (application.isReadAccessAllowed()) {
+ LOG.error("Calling write action from read-action leads to deadlock.");
+ }
+ else {
+ SwingUtilities.invokeAndWait(runnable);
+ }
}
catch (Exception e) {
if (isSilentExecution()) {
diff --git a/platform/lang-api/src/com/intellij/openapi/command/WriteCommandAction.java b/platform/core-api/src/com/intellij/openapi/command/WriteCommandAction.java
similarity index 83%
rename from platform/lang-api/src/com/intellij/openapi/command/WriteCommandAction.java
rename to platform/core-api/src/com/intellij/openapi/command/WriteCommandAction.java
index b7887d1..4be6c35 100644
--- a/platform/lang-api/src/com/intellij/openapi/command/WriteCommandAction.java
+++ b/platform/core-api/src/com/intellij/openapi/command/WriteCommandAction.java
@@ -15,23 +15,19 @@
*/
package com.intellij.openapi.command;
+import com.intellij.codeInsight.FileModificationService;
import com.intellij.openapi.application.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.ReadonlyStatusHandler;
-import com.intellij.openapi.vfs.VfsUtilCore;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
-import com.intellij.ui.GuiUtils;
-import com.intellij.util.SmartList;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collection;
-import java.util.List;
public abstract class WriteCommandAction<T> extends BaseActionRunnable<T> {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.command.WriteCommandAction");
@@ -84,11 +80,14 @@
}
};
Application application = ApplicationManager.getApplication();
- if (application.isWriteAccessAllowed() || application.isDispatchThread()) {
+ if (application.isDispatchThread()) {
runnable.run();
}
+ else if (application.isReadAccessAllowed()) {
+ LOG.error("Calling write command from read-action leads to deadlock.");
+ }
else {
- GuiUtils.invokeAndWait(runnable);
+ SwingUtilities.invokeAndWait(runnable);
}
}
catch (InvocationTargetException e) {
@@ -99,26 +98,11 @@
}
public static boolean ensureFilesWritable(@NotNull final Project project, @NotNull final Collection<PsiFile> psiFiles) {
- if (!psiFiles.isEmpty()) {
- List<VirtualFile> list = new SmartList<VirtualFile>();
- for (final PsiFile psiFile : psiFiles) {
- if (psiFile == null) continue;
- final VirtualFile virtualFile = psiFile.getVirtualFile();
- if (virtualFile != null) {
- list.add(virtualFile);
- }
- }
- if (!list.isEmpty()) {
- if (ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(VfsUtilCore.toVirtualFileArray(list)).hasReadonlyFiles()) {
- return false;
- }
- }
- }
- return true;
+ return FileModificationService.getInstance().preparePsiElementsForWrite(psiFiles);
}
private void performWriteCommandAction(final RunResult<T> result) {
- if (myProject != null && !ensureFilesWritable(myProject, Arrays.asList(myPsiFiles))) return;
+ if (!FileModificationService.getInstance().preparePsiElementsForWrite(Arrays.asList(myPsiFiles))) return;
//this is needed to prevent memory leak, since command
// is put into undo queue
diff --git a/platform/core-api/src/com/intellij/psi/search/LocalSearchScope.java b/platform/core-api/src/com/intellij/psi/search/LocalSearchScope.java
index 0f556dc..7b94ad1 100644
--- a/platform/core-api/src/com/intellij/psi/search/LocalSearchScope.java
+++ b/platform/core-api/src/com/intellij/psi/search/LocalSearchScope.java
@@ -22,7 +22,7 @@
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
-import com.intellij.psi.stubs.StubElement;
+import com.intellij.psi.StubBasedPsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NotNull;
@@ -74,7 +74,7 @@
localScope.add(file);
}
}
- else if (element instanceof StubElement || element.getTextRange() != null){
+ else if (element instanceof StubBasedPsiElement || element.getTextRange() != null){
localScope.add(element);
}
}
diff --git a/platform/core-api/src/com/intellij/psi/tree/IElementType.java b/platform/core-api/src/com/intellij/psi/tree/IElementType.java
index ed349f7..b64d761 100644
--- a/platform/core-api/src/com/intellij/psi/tree/IElementType.java
+++ b/platform/core-api/src/com/intellij/psi/tree/IElementType.java
@@ -51,7 +51,7 @@
};
public static final short FIRST_TOKEN_INDEX = 1;
- public static final short MAX_INDEXED_TYPES = 20000;
+ public static final short MAX_INDEXED_TYPES = 15000;
private static short ourCounter = FIRST_TOKEN_INDEX;
private static IElementType[] ourRegistry = new IElementType[700];
diff --git a/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java b/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java
index 334feb7..1948ff4 100644
--- a/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java
+++ b/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java
@@ -476,9 +476,10 @@
final PsiElement element = originalFile.findElementAt(range.getStartOffset());
final int maxLength = range.getLength();
T parent = PsiTreeUtil.getParentOfType(element, elementClass, false);
- for (T next = parent ;
- next != null && next.getTextLength() <= maxLength;
- parent = next, next = PsiTreeUtil.getParentOfType(next, elementClass, true)) {
+ T next = parent ;
+ while (next != null && next.getTextLength() <= maxLength) {
+ parent = next;
+ next = PsiTreeUtil.getParentOfType(next, elementClass, true);
}
return parent;
}
diff --git a/platform/core-impl/src/com/intellij/openapi/vfs/local/CoreLocalVirtualFile.java b/platform/core-impl/src/com/intellij/openapi/vfs/local/CoreLocalVirtualFile.java
index d914256..c3b770a 100644
--- a/platform/core-impl/src/com/intellij/openapi/vfs/local/CoreLocalVirtualFile.java
+++ b/platform/core-impl/src/com/intellij/openapi/vfs/local/CoreLocalVirtualFile.java
@@ -35,9 +35,13 @@
private final boolean isDirectory;
public CoreLocalVirtualFile(@NotNull CoreLocalFileSystem fileSystem, @NotNull File ioFile) {
+ this(fileSystem, ioFile, ioFile.isDirectory());
+ }
+
+ public CoreLocalVirtualFile(@NotNull CoreLocalFileSystem fileSystem, @NotNull File ioFile, boolean isDirectory) {
myFileSystem = fileSystem;
myIoFile = ioFile;
- isDirectory = ioFile.isDirectory();
+ this.isDirectory = isDirectory;
}
@NotNull
diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java
index 5fefd4f..3e8c237 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java
@@ -39,9 +39,7 @@
final MessageBus bus = project.getMessageBus();
myPublisher = bus.syncPublisher(TOPIC);
bus.connect().subscribe(DumbService.DUMB_MODE, new DumbService.DumbModeListener() {
-
- @Override
- public void enteredDumbMode() {
+ private void doIncCounter() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -51,8 +49,13 @@
}
@Override
+ public void enteredDumbMode() {
+ doIncCounter();
+ }
+
+ @Override
public void exitDumbMode() {
- enteredDumbMode();
+ doIncCounter();
}
});
}
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java
index c490e67..ccfa8b0 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java
@@ -19,6 +19,7 @@
import com.intellij.lang.LighterASTNode;
import com.intellij.lang.LighterASTTokenNode;
import com.intellij.lang.LighterLazyParseableNode;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.SmartList;
@@ -86,7 +87,12 @@
@NotNull
public static String toFilteredString(@NotNull LighterAST tree, @NotNull LighterASTNode node, @Nullable TokenSet skipTypes) {
- StringBuilder buffer = new StringBuilder(node.getEndOffset() - node.getStartOffset());
+ int length = node.getEndOffset() - node.getStartOffset();
+ if (length < 0) {
+ length = 0;
+ Logger.getInstance(LightTreeUtil.class).error("tree=" + tree + " node=" + node);
+ }
+ StringBuilder buffer = new StringBuilder(length);
toBuffer(tree, node, buffer, skipTypes);
return buffer.toString();
}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java
index 03e2758..7ce253c 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java
@@ -541,13 +541,15 @@
* <p/>
* However, we do allow to explicitly configure the ide to work with third-party external system api from the ide process.
* <p/>
- * This method allows to check whether the ide is configured to use 'out of process' or 'in process' mode.
- *
+ * This method allows to check whether the ide is configured to use 'out of process' or 'in process' mode for the system.
+ *
+ * @param externalSystemId target external system
+ *
* @return <code>true</code> if the ide is configured to work with external system api from the ide process;
- * <code>false</code> otherwise
+ * <code>false</code> otherwise
*/
- public static boolean isInProcessMode() {
- return Registry.is(ExternalSystemConstants.USE_IN_PROCESS_COMMUNICATION_REGISTRY_KEY, false);
+ public static boolean isInProcessMode(ProjectSystemId externalSystemId) {
+ return Registry.is(externalSystemId.getId() + ExternalSystemConstants.USE_IN_PROCESS_COMMUNICATION_REGISTRY_KEY_SUFFIX, false);
}
/**
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java
index 659a32d..c7232c0 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java
@@ -33,7 +33,7 @@
@NonNls @NotNull public static final String TOOL_WINDOW_PLACE = "ExternalSystem.ToolWindow";
@NonNls @NotNull public static final String TREE_CONTEXT_MENU_PLACE = "ExternalSystem.Tree.Context.Menu";
- @NotNull @NonNls public static final String USE_IN_PROCESS_COMMUNICATION_REGISTRY_KEY = "external.system.in.process";
+ @NotNull @NonNls public static final String USE_IN_PROCESS_COMMUNICATION_REGISTRY_KEY_SUFFIX = ".system.in.process";
@NotNull public static final String DEBUG_RUNNER_ID = "ExternalSystemTaskDebugRunner";
@NotNull public static final String RUNNER_ID = "ExternalSystemTaskRunner";
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeManager.java
index 862d603..edf4fee 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeManager.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeManager.java
@@ -28,7 +28,6 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -51,11 +50,6 @@
= ContainerUtil.newConcurrentMap();
@NotNull private final Lock myLock = new ReentrantLock();
- @NotNull private final AtomicBoolean myInProcessCommunication = new AtomicBoolean();
-
- @NotNull private final AtomicReference<ExternalSystemCommunicationManager> myCommunicationManager =
- new AtomicReference<ExternalSystemCommunicationManager>();
-
@NotNull private final RemoteExternalSystemProgressNotificationManager myProgressManager;
@NotNull private final RemoteExternalSystemCommunicationManager myRemoteCommunicationManager;
@@ -68,9 +62,6 @@
myProgressManager = (RemoteExternalSystemProgressNotificationManager)notificationManager;
myRemoteCommunicationManager = remoteCommunicationManager;
myInProcessCommunicationManager = inProcessCommunicationManager;
- boolean inProcessCommunication = ExternalSystemApiUtil.isInProcessMode();
- myInProcessCommunication.set(inProcessCommunication);
- myCommunicationManager.set(inProcessCommunication ? myInProcessCommunicationManager : myRemoteCommunicationManager);
}
@NotNull
@@ -157,33 +148,29 @@
@SuppressWarnings("ConstantConditions")
@NotNull
private RemoteExternalSystemFacade doGetFacade(@NotNull IntegrationKey key, @NotNull Project project) throws Exception {
- boolean currentInProcess = ExternalSystemApiUtil.isInProcessMode();
- if (myInProcessCommunication.getAndSet(currentInProcess) != currentInProcess) {
- myCommunicationManager.get().clear();
- myCommunicationManager.set(currentInProcess ? myInProcessCommunicationManager : myRemoteCommunicationManager);
- }
+ final boolean currentInProcess = ExternalSystemApiUtil.isInProcessMode(key.getExternalSystemId());
+ final ExternalSystemCommunicationManager myCommunicationManager = currentInProcess ? myInProcessCommunicationManager : myRemoteCommunicationManager;
ExternalSystemManager manager = ExternalSystemApiUtil.getManager(key.getExternalSystemId());
if (project.isDisposed() || manager == null) {
return RemoteExternalSystemFacade.NULL_OBJECT;
}
Pair<RemoteExternalSystemFacade, ExternalSystemExecutionSettings> pair = myRemoteFacades.get(key);
- if (pair != null && prepare(project, key, pair)) {
+ if (pair != null && prepare(myCommunicationManager, project, key, pair)) {
return pair.first;
}
myLock.lock();
try {
pair = myRemoteFacades.get(key);
- if (pair != null && prepare(project, key, pair)) {
+ if (pair != null && prepare(myCommunicationManager, project, key, pair)) {
return pair.first;
}
if (pair != null) {
- myCommunicationManager.get().clear();
myFacadeWrappers.clear();
myRemoteFacades.clear();
}
- return doCreateFacade(key, project);
+ return doCreateFacade(key, project, myCommunicationManager);
}
finally {
myLock.unlock();
@@ -192,15 +179,15 @@
@SuppressWarnings("unchecked")
@NotNull
- private RemoteExternalSystemFacade doCreateFacade(@NotNull IntegrationKey key, @NotNull Project project) throws Exception {
- final RemoteExternalSystemFacade facade = myCommunicationManager.get().acquire(project.getName(), key.getExternalSystemId());
+ private RemoteExternalSystemFacade doCreateFacade(@NotNull IntegrationKey key, @NotNull Project project,
+ @NotNull ExternalSystemCommunicationManager communicationManager) throws Exception {
+ final RemoteExternalSystemFacade facade = communicationManager.acquire(project.getName(), key.getExternalSystemId());
if (facade == null) {
throw new IllegalStateException("Can't obtain facade to working with external api at the remote process. Project: " + project);
}
Disposer.register(project, new Disposable() {
@Override
public void dispose() {
- myCommunicationManager.get().clear();
myFacadeWrappers.clear();
myRemoteFacades.clear();
}
@@ -215,11 +202,11 @@
}
@SuppressWarnings("unchecked")
- private boolean prepare(@NotNull Project project,
- @NotNull IntegrationKey key,
+ private boolean prepare(@NotNull ExternalSystemCommunicationManager communicationManager,
+ @NotNull Project project, @NotNull IntegrationKey key,
@NotNull Pair<RemoteExternalSystemFacade, ExternalSystemExecutionSettings> pair)
{
- if (!myCommunicationManager.get().isAlive(pair.first)) {
+ if (!communicationManager.isAlive(pair.first)) {
return false;
}
try {
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java
index 061a88c..a0ea3e4 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java
@@ -148,7 +148,7 @@
}
String vmOptions;
if (myDebugPort > 0) {
- String debuggerSetup = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=" + myDebugPort;
+ String debuggerSetup = "-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=" + myDebugPort;
String regular = mySettings.getVmOptions();
vmOptions = regular == null ? debuggerSetup : regular + " " + debuggerSetup;
}
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskDebugRunner.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskDebugRunner.java
index b0d18c6..71b74f6 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskDebugRunner.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskDebugRunner.java
@@ -59,7 +59,7 @@
if (state instanceof ExternalSystemRunConfiguration.MyRunnableState) {
int port = ((ExternalSystemRunConfiguration.MyRunnableState)state).getDebugPort();
if (port > 0) {
- RemoteConnection connection = new RemoteConnection(true, "127.0.0.1", String.valueOf(port), false);
+ RemoteConnection connection = new RemoteConnection(true, "127.0.0.1", String.valueOf(port), true);
return attachVirtualMachine(project, state, contentToReuse, env, connection, true);
}
else {
diff --git a/platform/icons/src/fileTypes/manifest.png b/platform/icons/src/fileTypes/manifest.png
new file mode 100644
index 0000000..df581b3
--- /dev/null
+++ b/platform/icons/src/fileTypes/manifest.png
Binary files differ
diff --git a/platform/icons/src/fileTypes/manifest@2x.png b/platform/icons/src/fileTypes/manifest@2x.png
new file mode 100644
index 0000000..8513230
--- /dev/null
+++ b/platform/icons/src/fileTypes/manifest@2x.png
Binary files differ
diff --git a/platform/lang-api/src/com/intellij/lang/findUsages/package.html b/platform/indexing-api/src/com/intellij/lang/findUsages/package.html
similarity index 100%
rename from platform/lang-api/src/com/intellij/lang/findUsages/package.html
rename to platform/indexing-api/src/com/intellij/lang/findUsages/package.html
diff --git a/platform/indexing-api/src/com/intellij/psi/stubs/StringStubIndexExtension.java b/platform/indexing-api/src/com/intellij/psi/stubs/StringStubIndexExtension.java
index 8aacbce..0e4cd6b 100644
--- a/platform/indexing-api/src/com/intellij/psi/stubs/StringStubIndexExtension.java
+++ b/platform/indexing-api/src/com/intellij/psi/stubs/StringStubIndexExtension.java
@@ -33,4 +33,8 @@
public KeyDescriptor<String> getKeyDescriptor() {
return new EnumeratorStringDescriptor();
}
+
+ public boolean traceKeyHashToVirtualFileMapping() {
+ return false;
+ }
}
\ No newline at end of file
diff --git a/platform/indexing-api/src/com/intellij/psi/stubs/StubIndex.java b/platform/indexing-api/src/com/intellij/psi/stubs/StubIndex.java
index eee5e64..bbe7324 100644
--- a/platform/indexing-api/src/com/intellij/psi/stubs/StubIndex.java
+++ b/platform/indexing-api/src/com/intellij/psi/stubs/StubIndex.java
@@ -28,7 +28,9 @@
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.Processor;
import com.intellij.util.indexing.FileBasedIndex;
+import com.intellij.util.indexing.IdFilter;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Iterator;
@@ -59,6 +61,10 @@
public abstract <K> boolean processAllKeys(@NotNull StubIndexKey<K, ?> indexKey, @NotNull Project project, Processor<K> processor);
+ public <K> boolean processAllKeys(@NotNull StubIndexKey<K, ?> indexKey, Processor<K> processor, GlobalSearchScope scope, @Nullable IdFilter idFilter) {
+ return processAllKeys(indexKey, scope.getProject(), processor);
+ }
+
public <Key, Psi extends PsiElement> Collection<Psi> safeGet(@NotNull StubIndexKey<Key, Psi> indexKey,
@NotNull Key key,
@NotNull final Project project,
diff --git a/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java b/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java
index 6d07a27..9260714 100644
--- a/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java
+++ b/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndex.java
@@ -126,6 +126,10 @@
*/
public abstract <K> boolean processAllKeys(@NotNull ID<K, ?> indexId, Processor<K> processor, @Nullable Project project);
+ public <K> boolean processAllKeys(@NotNull ID<K, ?> indexId, @NotNull Processor<K> processor, @NotNull GlobalSearchScope scope, @Nullable IdFilter idFilter) {
+ return processAllKeys(indexId, processor, scope.getProject());
+ }
+
public interface ValueProcessor<V> {
/**
* @param value a value to process
@@ -145,4 +149,7 @@
public interface FileTypeSpecificInputFilter extends InputFilter {
void registerFileTypesUsedForIndexing(@NotNull Consumer<FileType> fileTypeSink);
}
+
+ // TODO: remove once changes becomes permamnent
+ public static final boolean ourEnableTracingOfKeyHashToVirtualFileMapping = ApplicationManager.getApplication().isInternal();
}
diff --git a/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.java b/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.java
index 14fcf80..0dc808f 100644
--- a/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.java
+++ b/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.java
@@ -80,6 +80,10 @@
return false;
}
+ public boolean traceKeyHashToVirtualFileMapping() {
+ return false;
+ }
+
/** Per-filetype index version support */
public Map<FileType, Integer> getVersionMap() {
return Collections.emptyMap();
diff --git a/platform/indexing-api/src/com/intellij/util/indexing/IdFilter.java b/platform/indexing-api/src/com/intellij/util/indexing/IdFilter.java
new file mode 100644
index 0000000..c4b7550
--- /dev/null
+++ b/platform/indexing-api/src/com/intellij/util/indexing/IdFilter.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.util.indexing;
+
+/**
+* Created by Maxim.Mossienko on 8/14/13.
+*/
+public abstract class IdFilter {
+ public abstract boolean contains(int id);
+}
diff --git a/platform/indexing-impl/src/com/intellij/psi/search/FilenameIndex.java b/platform/indexing-impl/src/com/intellij/psi/search/FilenameIndex.java
index ededc778..641751a 100644
--- a/platform/indexing-impl/src/com/intellij/psi/search/FilenameIndex.java
+++ b/platform/indexing-impl/src/com/intellij/psi/search/FilenameIndex.java
@@ -71,7 +71,7 @@
@Override
public int getVersion() {
- return 1;
+ return 1 + (FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping ? 1 : 0);
}
public static String[] getAllFilenames(Project project) {
@@ -160,4 +160,9 @@
}
return files;
}
+
+ @Override
+ public boolean traceKeyHashToVirtualFileMapping() {
+ return FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping;
+ }
}
diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java
index 6ba89a9..ab7b43c 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionConfidence.java
@@ -31,6 +31,10 @@
@NotNull
public abstract ThreeState shouldFocusLookup(@NotNull CompletionParameters parameters);
+ /**
+ * This method is invoked first when a completion autopopup is scheduled. Extensions are able to cancel this completion process based on location.
+ * For example, in string literals or comments completion autopopup may do more harm than good.
+ */
@NotNull
public ThreeState shouldSkipAutopopup(@NotNull PsiElement contextElement, @NotNull PsiFile psiFile, int offset) {
return ThreeState.UNSURE;
diff --git a/platform/lang-api/src/com/intellij/codeInsight/daemon/QuickFixActionRegistrar.java b/platform/lang-api/src/com/intellij/codeInsight/daemon/QuickFixActionRegistrar.java
index ea79f57..2194bbe 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/daemon/QuickFixActionRegistrar.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/daemon/QuickFixActionRegistrar.java
@@ -19,15 +19,16 @@
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
public interface QuickFixActionRegistrar {
- void register(IntentionAction action);
- void register(TextRange fixRange, IntentionAction action, HighlightDisplayKey key);
+ void register(@NotNull IntentionAction action);
+ void register(@NotNull TextRange fixRange, @NotNull IntentionAction action, HighlightDisplayKey key);
/**
* Allows to replace some of the built-in quickfixes.
* @param condition condition for quickfixes to remove
* @since 9.0
*/
- void unregister(Condition<IntentionAction> condition);
+ void unregister(@NotNull Condition<IntentionAction> condition);
}
diff --git a/platform/lang-api/src/com/intellij/codeInsight/generation/actions/GenerateActionPopupTemplateInjector.java b/platform/lang-api/src/com/intellij/codeInsight/generation/actions/GenerateActionPopupTemplateInjector.java
new file mode 100644
index 0000000..56868fe
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/codeInsight/generation/actions/GenerateActionPopupTemplateInjector.java
@@ -0,0 +1,28 @@
+/*
+ * 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.generation.actions;
+
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.DataContext;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Generate action could provide an action to edit corresponding file template. It would appear then in the subMenu of the Generate... popup
+ */
+public interface GenerateActionPopupTemplateInjector {
+ @Nullable
+ AnAction createEditTemplateAction(DataContext dataContext);
+}
diff --git a/platform/lang-api/src/com/intellij/lang/annotation/AnnotationHolder.java b/platform/lang-api/src/com/intellij/lang/annotation/AnnotationHolder.java
index 3fcbc8c..ea076d2 100644
--- a/platform/lang-api/src/com/intellij/lang/annotation/AnnotationHolder.java
+++ b/platform/lang-api/src/com/intellij/lang/annotation/AnnotationHolder.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.
@@ -27,7 +27,6 @@
* @author max
* @see Annotator#annotate(com.intellij.psi.PsiElement, AnnotationHolder)
*/
-
public interface AnnotationHolder {
/**
* Creates an error annotation with the specified message over the specified PSI element.
@@ -84,35 +83,34 @@
Annotation createWarningAnnotation(@NotNull TextRange range, @Nullable String message);
/**
- * Creates an annotation with severity {@link HighlightSeverity#WEAK_WARNING} ('weak warning') with the specified
- * message over the specified PSI element.
- *
- * @param elt the element over which the annotation is created.
- * @param message the info message.
- * @return the annotation (which can be modified to set additional annotation parameters)
- */
- Annotation createWeakWarningAnnotation(@NotNull PsiElement elt, @Nullable String message);
+ * Creates an annotation with severity {@link HighlightSeverity#WEAK_WARNING} ('weak warning') with the specified
+ * message over the specified PSI element.
+ *
+ * @param elt the element over which the annotation is created.
+ * @param message the info message.
+ * @return the annotation (which can be modified to set additional annotation parameters)
+ */
+ Annotation createWeakWarningAnnotation(@NotNull PsiElement elt, @Nullable String message);
- /**
- * Creates an annotation with severity {@link HighlightSeverity#WEAK_WARNING} ('weak warning') with the specified
- * message over the specified AST node.
- *
- * @param node the node over which the annotation is created.
- * @param message the info message.
- * @return the annotation (which can be modified to set additional annotation parameters)
- */
- Annotation createWeakWarningAnnotation(@NotNull ASTNode node, @Nullable String message);
+ /**
+ * Creates an annotation with severity {@link HighlightSeverity#WEAK_WARNING} ('weak warning') with the specified
+ * message over the specified AST node.
+ *
+ * @param node the node over which the annotation is created.
+ * @param message the info message.
+ * @return the annotation (which can be modified to set additional annotation parameters)
+ */
+ Annotation createWeakWarningAnnotation(@NotNull ASTNode node, @Nullable String message);
- /**
- * Creates an annotation with severity {@link HighlightSeverity#WEAK_WARNING} ('weak warning') with the specified
- * message over the specified text range.
- *
- * @param range the text range over which the annotation is created.
- * @param message the info message.
- * @return the annotation (which can be modified to set additional annotation parameters)
- */
- Annotation createWeakWarningAnnotation(@NotNull TextRange range, @Nullable String message);
-
+ /**
+ * Creates an annotation with severity {@link HighlightSeverity#WEAK_WARNING} ('weak warning') with the specified
+ * message over the specified text range.
+ *
+ * @param range the text range over which the annotation is created.
+ * @param message the info message.
+ * @return the annotation (which can be modified to set additional annotation parameters)
+ */
+ Annotation createWeakWarningAnnotation(@NotNull TextRange range, @Nullable String message);
/**
* Creates an information annotation (colored highlighting only, with no gutter mark and not participating in
@@ -144,7 +142,6 @@
*/
Annotation createInfoAnnotation(@NotNull TextRange range, @Nullable String message);
-
@NotNull
AnnotationSession getCurrentAnnotationSession();
diff --git a/platform/lang-api/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java b/platform/lang-api/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java
index 4f2f65b..ccc4fed 100644
--- a/platform/lang-api/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java
+++ b/platform/lang-api/src/com/intellij/lang/refactoring/RefactoringSupportProvider.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.
@@ -44,7 +44,7 @@
* @param element the element for which Safe Delete was invoked
* @return true if Safe Delete is available, false otherwise.
*/
- public boolean isSafeDeleteAvailable(PsiElement element) { return false; }
+ public boolean isSafeDeleteAvailable(@NotNull PsiElement element) { return false; }
/**
* @return handler for introducing local variables in this language
@@ -123,9 +123,9 @@
@Nullable
public ChangeSignatureHandler getChangeSignatureHandler() { return null; }
- public boolean isInplaceRenameAvailable(PsiElement element, PsiElement context) { return false; }
+ public boolean isInplaceRenameAvailable(@NotNull PsiElement element, PsiElement context) { return false; }
- public boolean isInplaceIntroduceAvailable(PsiElement element, PsiElement context) {
+ public boolean isInplaceIntroduceAvailable(@NotNull PsiElement element, PsiElement context) {
return false;
}
@@ -138,7 +138,7 @@
return null;
}
- public boolean isMemberInplaceRenameAvailable(PsiElement element, PsiElement context) {
+ public boolean isMemberInplaceRenameAvailable(@NotNull PsiElement element, @Nullable PsiElement context) {
return false;
}
}
diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java
index 5d7ae51..cf5d538 100644
--- a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java
+++ b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java
@@ -19,7 +19,6 @@
import com.intellij.application.options.OptionsContainingConfigurable;
import com.intellij.application.options.editor.EditorOptionsProvider;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
-import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
import com.intellij.execution.impl.ConsoleViewUtil;
import com.intellij.ide.ui.LafManager;
import com.intellij.ide.ui.laf.darcula.DarculaInstaller;
@@ -56,6 +55,8 @@
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.FileStatusFactory;
import com.intellij.openapi.vcs.FileStatusManager;
+import com.intellij.packageDependencies.DependencyValidationManager;
+import com.intellij.packageDependencies.DependencyValidationManagerImpl;
import com.intellij.psi.codeStyle.DisplayPriority;
import com.intellij.psi.codeStyle.DisplayPrioritySortable;
import com.intellij.psi.search.scope.packageSet.NamedScope;
@@ -151,15 +152,16 @@
return mySelectedScheme.getDescriptors();
}
- public static boolean isReadOnly(final EditorColorsScheme scheme) {
+ public static boolean isReadOnly(@NotNull final EditorColorsScheme scheme) {
return ((MyColorScheme)scheme).isReadOnly();
}
+ @NotNull
public String[] getSchemeNames() {
- ArrayList<MyColorScheme> schemes = new ArrayList<MyColorScheme>(mySchemes.values());
+ List<MyColorScheme> schemes = new ArrayList<MyColorScheme>(mySchemes.values());
Collections.sort(schemes, new Comparator<MyColorScheme>() {
@Override
- public int compare(MyColorScheme o1, MyColorScheme o2) {
+ public int compare(@NotNull MyColorScheme o1, @NotNull MyColorScheme o2) {
if (isReadOnly(o1) && !isReadOnly(o2)) return -1;
if (!isReadOnly(o1) && isReadOnly(o2)) return 1;
@@ -167,7 +169,7 @@
}
});
- ArrayList<String> names = new ArrayList<String>(schemes.size());
+ List<String> names = new ArrayList<String>(schemes.size());
for (MyColorScheme scheme : schemes) {
names.add(scheme.getName());
}
@@ -175,6 +177,7 @@
return ArrayUtil.toStringArray(names);
}
+ @NotNull
public Collection<EditorColorsScheme> getSchemes() {
return new ArrayList<EditorColorsScheme>(mySchemes.values());
}
@@ -198,7 +201,7 @@
resetSchemesCombo(null);
}
- public void addImportedScheme(final EditorColorsScheme imported) {
+ public void addImportedScheme(@NotNull final EditorColorsScheme imported) {
MyColorScheme newScheme = new MyColorScheme(imported);
initScheme(newScheme);
@@ -312,6 +315,7 @@
return true;
}
+ @NotNull
@Override
public Configurable[] buildConfigurables() {
myDisposeCompleted = false;
@@ -329,6 +333,7 @@
return result.toArray(new Configurable[result.size()]);
}
+ @NotNull
private Set<NewColorAndFontPanel> getPanels() {
Set<NewColorAndFontPanel> result = new HashSet<NewColorAndFontPanel>();
for (InnerSearchableConfigurable configurable : mySubPanelFactories.values()) {
@@ -341,7 +346,7 @@
}
protected List<ColorAndFontPanelFactory> createPanelFactories() {
- ArrayList<ColorAndFontPanelFactory> result = new ArrayList<ColorAndFontPanelFactory>();
+ List<ColorAndFontPanelFactory> result = new ArrayList<ColorAndFontPanelFactory>();
result.add(new FontConfigurableFactory());
List<ColorAndFontPanelFactory> extensions = new ArrayList<ColorAndFontPanelFactory>();
@@ -443,6 +448,7 @@
return "Console Font";
}
+ @NotNull
@Override
public DisplayPriority getPriority() {
return DisplayPriority.COMMON_SETTINGS;
@@ -499,8 +505,8 @@
assert mySelectedScheme != null : EditorColorsManager.getInstance().getGlobalScheme().getName() + "; myschemes=" + mySchemes;
}
- private static void initScheme(MyColorScheme scheme) {
- ArrayList<EditorSchemeAttributeDescriptor> descriptions = new ArrayList<EditorSchemeAttributeDescriptor>();
+ private static void initScheme(@NotNull MyColorScheme scheme) {
+ List<EditorSchemeAttributeDescriptor> descriptions = new ArrayList<EditorSchemeAttributeDescriptor>();
initPluggedDescriptions(descriptions, scheme);
initDiffDescriptors(descriptions, scheme);
initFileStatusDescriptors(descriptions, scheme);
@@ -509,7 +515,7 @@
scheme.setDescriptors(descriptions.toArray(new EditorSchemeAttributeDescriptor[descriptions.size()]));
}
- private static void initPluggedDescriptions(ArrayList<EditorSchemeAttributeDescriptor> descriptions, MyColorScheme scheme) {
+ private static void initPluggedDescriptions(@NotNull List<EditorSchemeAttributeDescriptor> descriptions, @NotNull MyColorScheme scheme) {
ColorSettingsPage[] pages = ColorSettingsPages.getInstance().getRegisteredPages();
for (ColorSettingsPage page : pages) {
initDescriptions(page, descriptions, scheme);
@@ -519,9 +525,9 @@
}
}
- private static void initDescriptions(ColorAndFontDescriptorsProvider provider,
- ArrayList<EditorSchemeAttributeDescriptor> descriptions,
- MyColorScheme scheme) {
+ private static void initDescriptions(@NotNull ColorAndFontDescriptorsProvider provider,
+ @NotNull List<EditorSchemeAttributeDescriptor> descriptions,
+ @NotNull MyColorScheme scheme) {
String group = provider.getDisplayName();
List<AttributesDescriptor> attributeDescriptors = ColorSettingsUtil.getAllAttributeDescriptors(provider);
for (AttributesDescriptor descriptor : attributeDescriptors) {
@@ -536,11 +542,11 @@
}
}
- private static void initDiffDescriptors(ArrayList<EditorSchemeAttributeDescriptor> descriptions, MyColorScheme scheme) {
+ private static void initDiffDescriptors(@NotNull List<EditorSchemeAttributeDescriptor> descriptions, @NotNull MyColorScheme scheme) {
DiffOptionsPanel.addSchemeDescriptions(descriptions, scheme);
}
- private static void initFileStatusDescriptors(ArrayList<EditorSchemeAttributeDescriptor> descriptions, MyColorScheme scheme) {
+ private static void initFileStatusDescriptors(@NotNull List<EditorSchemeAttributeDescriptor> descriptions, MyColorScheme scheme) {
FileStatus[] statuses = FileStatusFactory.getInstance().getAllFileStatuses();
@@ -554,22 +560,22 @@
}
}
- private static void initScopesDescriptors(ArrayList<EditorSchemeAttributeDescriptor> descriptions, MyColorScheme scheme) {
+ private static void initScopesDescriptors(@NotNull List<EditorSchemeAttributeDescriptor> descriptions, @NotNull MyColorScheme scheme) {
Set<Pair<NamedScope,NamedScopesHolder>> namedScopes = new THashSet<Pair<NamedScope,NamedScopesHolder>>(new TObjectHashingStrategy<Pair<NamedScope,NamedScopesHolder>>() {
@Override
- public int computeHashCode(final Pair<NamedScope, NamedScopesHolder> object) {
+ public int computeHashCode(@NotNull final Pair<NamedScope, NamedScopesHolder> object) {
return object.getFirst().getName().hashCode();
}
@Override
- public boolean equals(final Pair<NamedScope, NamedScopesHolder> o1, final Pair<NamedScope, NamedScopesHolder> o2) {
+ public boolean equals(@NotNull final Pair<NamedScope, NamedScopesHolder> o1, @NotNull final Pair<NamedScope, NamedScopesHolder> o2) {
return o1.getFirst().getName().equals(o2.getFirst().getName());
}
});
Project[] projects = ProjectManager.getInstance().getOpenProjects();
for (Project project : projects) {
- DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(project);
- List<Pair<NamedScope,NamedScopesHolder>> cachedScopes = codeAnalyzer.getScopeBasedHighlightingCachedScopes();
+ DependencyValidationManagerImpl validationManager = (DependencyValidationManagerImpl)DependencyValidationManager.getInstance(project);
+ List<Pair<NamedScope,NamedScopesHolder>> cachedScopes = validationManager.getScopeBasedHighlightingCachedScopes();
namedScopes.addAll(cachedScopes);
}
@@ -577,14 +583,14 @@
Collections.sort(list, new Comparator<Pair<NamedScope,NamedScopesHolder>>() {
@Override
- public int compare(final Pair<NamedScope,NamedScopesHolder> o1, final Pair<NamedScope,NamedScopesHolder> o2) {
+ public int compare(@NotNull final Pair<NamedScope,NamedScopesHolder> o1, @NotNull final Pair<NamedScope,NamedScopesHolder> o2) {
return o1.getFirst().getName().compareToIgnoreCase(o2.getFirst().getName());
}
});
for (Pair<NamedScope,NamedScopesHolder> pair : list) {
NamedScope namedScope = pair.getFirst();
String name = namedScope.getName();
- TextAttributesKey textAttributesKey = getScopeTextAttributeKey(name);
+ TextAttributesKey textAttributesKey = ScopeAttributesUtil.getScopeTextAttributeKey(name);
if (scheme.getAttributes(textAttributesKey) == null) {
scheme.setAttributes(textAttributesKey, new TextAttributes());
}
@@ -600,16 +606,12 @@
}
}
- public static TextAttributesKey getScopeTextAttributeKey(final String scope) {
- return TextAttributesKey.find("SCOPE_KEY_" + scope);
- }
-
- private static void addEditorSettingDescription(ArrayList<EditorSchemeAttributeDescriptor> array,
- String name,
- String group,
- ColorKey backgroundKey,
- ColorKey foregroundKey,
- EditorColorsScheme scheme) {
+ private static void addEditorSettingDescription(@NotNull List<EditorSchemeAttributeDescriptor> array,
+ String name,
+ String group,
+ @Nullable ColorKey backgroundKey,
+ @Nullable ColorKey foregroundKey,
+ EditorColorsScheme scheme) {
String type = null;
if (foregroundKey != null) {
type = foregroundKey.getExternalName();
@@ -623,8 +625,11 @@
array.add(descr);
}
- private static void addSchemedDescription(ArrayList<EditorSchemeAttributeDescriptor> array, String name, String group, TextAttributesKey key,
- MyColorScheme scheme,
+ private static void addSchemedDescription(@NotNull List<EditorSchemeAttributeDescriptor> array,
+ String name,
+ String group,
+ @NotNull TextAttributesKey key,
+ @NotNull MyColorScheme scheme,
Icon icon,
String toolTip) {
ColorAndFontDescription descr = new SchemeTextAttributesDescription(name, group, key, scheme, icon, toolTip);
@@ -757,12 +762,12 @@
private static class SchemeTextAttributesDescription extends TextAttributesDescription {
- private final TextAttributes myAttributesToApply;
- private final TextAttributesKey key;
+ @NotNull private final TextAttributes myAttributesToApply;
+ @NotNull private final TextAttributesKey key;
private TextAttributes myFallbackAttributes;
private Pair<ColorSettingsPage,AttributesDescriptor> myBaseAttributeDescriptor;
- private SchemeTextAttributesDescription(String name, String group, TextAttributesKey key, MyColorScheme scheme, Icon icon,
+ private SchemeTextAttributesDescription(String name, String group, @NotNull TextAttributesKey key, @NotNull MyColorScheme scheme, Icon icon,
String toolTip) {
super(name, group,
getInitialAttributes(scheme, key).clone(),
@@ -783,7 +788,7 @@
@NotNull
- private static TextAttributes getInitialAttributes(MyColorScheme scheme, TextAttributesKey key) {
+ private static TextAttributes getInitialAttributes(@NotNull MyColorScheme scheme, @NotNull TextAttributesKey key) {
TextAttributes attributes = scheme.getAttributes(key);
TextAttributesKey fallbackKey = key.getFallbackAttributeKey();
if (fallbackKey != null && !scheme.containsKey(key)) {
@@ -798,9 +803,7 @@
@Override
public void apply(EditorColorsScheme scheme) {
if (scheme == null) scheme = getScheme();
- if (myAttributesToApply != null) {
- scheme.setAttributes(key, getTextAttributes());
- }
+ scheme.setAttributes(key, getTextAttributes());
}
@Override
@@ -900,6 +903,7 @@
public void setExternalEffectType(EffectType type) {
}
+ @NotNull
@Override
public EffectType getExternalEffectType() {
return EffectType.LINE_UNDERSCORE;
@@ -995,7 +999,7 @@
private String myName;
private boolean myIsNew = false;
- private MyColorScheme(EditorColorsScheme parentScheme) {
+ private MyColorScheme(@NotNull EditorColorsScheme parentScheme) {
super(parentScheme, DefaultColorSchemesManager.getInstance());
parentScheme.getFontPreferences().copyTo(getFontPreferences());
setLineSpacing(parentScheme.getLineSpacing());
@@ -1052,21 +1056,19 @@
private boolean isFontModified() {
if (!getFontPreferences().equals(myParentScheme.getFontPreferences())) return true;
if (getLineSpacing() != myParentScheme.getLineSpacing()) return true;
- if (getQuickDocFontSize() != myParentScheme.getQuickDocFontSize()) return true;
- return false;
+ return getQuickDocFontSize() != myParentScheme.getQuickDocFontSize();
}
private boolean isConsoleFontModified() {
if (!getConsoleFontPreferences().equals(myParentScheme.getConsoleFontPreferences())) return true;
- if (getConsoleLineSpacing() != myParentScheme.getConsoleLineSpacing()) return true;
- return false;
+ return getConsoleLineSpacing() != myParentScheme.getConsoleLineSpacing();
}
public void apply() {
apply(myParentScheme);
}
- public void apply(EditorColorsScheme scheme) {
+ public void apply(@NotNull EditorColorsScheme scheme) {
scheme.setFontPreferences(getFontPreferences());
scheme.setLineSpacing(myLineSpacing);
scheme.setQuickDocFontSize(getQuickDocFontSize());
@@ -1095,6 +1097,7 @@
return myIsNew;
}
+ @NotNull
@Override
public String toString() {
return "temporary scheme for " + myName;
@@ -1114,7 +1117,7 @@
}
@Nullable
- public InnerSearchableConfigurable findSubConfigurable(final Class pageClass) {
+ public InnerSearchableConfigurable findSubConfigurable(@NotNull final Class pageClass) {
if (mySubPanelFactories == null) {
buildConfigurables();
}
@@ -1142,12 +1145,13 @@
private class InnerSearchableConfigurable implements SearchableConfigurable, OptionsContainingConfigurable, NoScroll {
private NewColorAndFontPanel mySubPanel;
private boolean mySubInitInvoked = false;
- private final ColorAndFontPanelFactory myFactory;
+ @NotNull private final ColorAndFontPanelFactory myFactory;
private InnerSearchableConfigurable(@NotNull ColorAndFontPanelFactory factory) {
myFactory = factory;
}
+ @NotNull
@Override
@Nls
public String getDisplayName() {
@@ -1255,11 +1259,13 @@
return createPanel().showOption(option);
}
+ @NotNull
@Override
public Set<String> processListOptions() {
return createPanel().processListOptions();
}
+ @NotNull
@NonNls
@Override
public String toString() {
diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/ScopeAttributesUtil.java b/platform/lang-impl/src/com/intellij/application/options/colors/ScopeAttributesUtil.java
new file mode 100644
index 0000000..4466f68
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/application/options/colors/ScopeAttributesUtil.java
@@ -0,0 +1,26 @@
+/*
+ * 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.application.options.colors;
+
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import org.jetbrains.annotations.NotNull;
+
+public class ScopeAttributesUtil {
+ @NotNull
+ public static TextAttributesKey getScopeTextAttributeKey(@NotNull String scope) {
+ return TextAttributesKey.find("SCOPE_KEY_" + scope);
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightUtilBase.java b/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightUtilBase.java
index f788b04..7e9b614 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightUtilBase.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightUtilBase.java
@@ -49,23 +49,20 @@
final VirtualFile file = psiFile.getVirtualFile();
final Project project = psiFile.getProject();
- final Editor editor =
- psiFile.isWritable() ? null : FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file), true);
- if (!ReadonlyStatusHandler.ensureFilesWritable(project, file)) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- if (editor != null && editor.getComponent().isDisplayable()) {
- HintManager.getInstance()
- .showErrorHint(editor, CodeInsightBundle.message("error.hint.file.is.readonly", file.getPresentableUrl()));
- }
- }
- });
-
- return false;
+ if (ReadonlyStatusHandler.ensureFilesWritable(project, file)) {
+ return true;
}
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ final Editor editor = FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file), true);
+ if (editor != null && editor.getComponent().isDisplayable()) {
+ HintManager.getInstance().showErrorHint(editor, CodeInsightBundle.message("error.hint.file.is.readonly", file.getPresentableUrl()));
+ }
+ }
+ }, project.getDisposed());
- return true;
+ return false;
}
@Override
@@ -85,8 +82,9 @@
Set<VirtualFile> files = new THashSet<VirtualFile>();
Project project = null;
for (PsiElement element : elements) {
+ if (element == null) continue;
PsiFile file = element.getContainingFile();
- if (file == null) continue;
+ if (file == null || !file.isPhysical()) continue;
project = file.getProject();
VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile == null) continue;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java
index 5185944..76416e7 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java
@@ -226,7 +226,7 @@
ArrayList<LookupElement> result = new ArrayList<LookupElement>(model);
if (result.size() > 1) {
LookupElement first = result.get(0);
- if (isLiveTemplate(first) && isPrefixItem(lookup, first, true)) {
+ if (isLiveTemplate(first) && isPrefixItem(lookup, first, true) && CompletionServiceImpl.isStartMatch(result.get(1), lookup)) {
ContainerUtil.swapElements(result, 0, 1);
}
}
@@ -351,10 +351,14 @@
String selectedText = lookup.getEditor().getSelectionModel().getSelectedText();
for (int i = 0; i < items.size(); i++) {
LookupElement item = items.get(i);
- if (isAlphaSorted() && isPrefixItem(lookup, item, true) && !isLiveTemplate(item) ||
+ boolean isTemplate = isLiveTemplate(item);
+ if (isAlphaSorted() && isPrefixItem(lookup, item, true) && !isTemplate ||
item.getLookupString().equals(selectedText)) {
return i;
}
+ if (i == 0 && isTemplate && items.size() > 1 && !CompletionServiceImpl.isStartMatch(items.get(1), lookup)) {
+ return 0;
+ }
}
return Math.max(0, ContainerUtil.indexOfIdentity(items, mostRelevant));
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
index 23f337b..1062bd4 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
@@ -57,15 +57,12 @@
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.impl.PsiDocumentManagerImpl;
-import com.intellij.psi.search.scope.packageSet.NamedScope;
import com.intellij.psi.search.scope.packageSet.NamedScopeManager;
-import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.Alarm;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
-import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
@@ -146,14 +143,6 @@
assert !myInitialized : "Double Initializing";
Disposer.register(myProject, new StatusBarUpdater(myProject));
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- reloadScopes(dependencyValidationManager, namedScopeManager);
- }
- }, project.getDisposed());
-
-
myInitialized = true;
myDisposed = false;
myFileStatusMap.markAllFilesDirty();
@@ -261,6 +250,7 @@
if (callbackWhileWaiting != null) {
callbackWhileWaiting.run();
}
+ myPassExecutorService.waitFor(50);
UIUtil.dispatchAllInvocationEvents();
Throwable savedException = PassExecutorService.getSavedException(progress);
if (savedException != null) throw savedException;
@@ -323,31 +313,6 @@
TrafficLightRenderer.setOrRefreshErrorStripeRenderer(markup, myProject, document, psiFile);
}
- private final List<Pair<NamedScope, NamedScopesHolder>> myScopes = ContainerUtil.createLockFreeCopyOnWriteList();
-
- void reloadScopes(@NotNull DependencyValidationManager dependencyValidationManager, @NotNull NamedScopeManager namedScopeManager) {
- ApplicationManager.getApplication().assertIsDispatchThread();
- List<Pair<NamedScope, NamedScopesHolder>> scopeList = new ArrayList<Pair<NamedScope, NamedScopesHolder>>();
- addScopesToList(scopeList, namedScopeManager);
- addScopesToList(scopeList, dependencyValidationManager);
- myScopes.clear();
- myScopes.addAll(scopeList);
- dependencyValidationManager.reloadRules();
- }
-
- private static void addScopesToList(@NotNull final List<Pair<NamedScope, NamedScopesHolder>> scopeList,
- @NotNull final NamedScopesHolder holder) {
- NamedScope[] scopes = holder.getScopes();
- for (NamedScope scope : scopes) {
- scopeList.add(Pair.create(scope, holder));
- }
- }
-
- @NotNull
- public List<Pair<NamedScope, NamedScopesHolder>> getScopeBasedHighlightingCachedScopes() {
- return myScopes;
- }
-
@Override
public void settingsChanged() {
DaemonCodeAnalyzerSettings settings = DaemonCodeAnalyzerSettings.getInstance();
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java
index 95dc71a..dc09785 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java
@@ -71,11 +71,9 @@
import com.intellij.psi.impl.PsiDocumentManagerImpl;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.search.scope.packageSet.NamedScopeManager;
-import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.UIUtil;
-import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -85,7 +83,6 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import java.util.Set;
/**
@@ -328,21 +325,6 @@
((EditorEventMulticasterEx)eventMulticaster).addErrorStripeListener(new ErrorStripeHandler(myProject), this);
- Set<NamedScopesHolder> holders = new THashSet<NamedScopesHolder>(Arrays.asList(NamedScopesHolder.getAllNamedScopeHolders(project)));
- // to ensure initialization dependency
- holders.add(namedScopeManager);
- holders.add(dependencyValidationManager);
-
- NamedScopesHolder.ScopeListener scopeListener = new NamedScopesHolder.ScopeListener() {
- @Override
- public void scopesChanged() {
- myDaemonCodeAnalyzer.reloadScopes(dependencyValidationManager, namedScopeManager);
- }
- };
- for (NamedScopesHolder holder : holders) {
- holder.addScopeListener(scopeListener);
- }
-
ModalityStateListener modalityStateListener = new ModalityStateListener() {
@Override
public void beforeModalityStateChanged(boolean entering) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
index f2825cb..f704286 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
@@ -102,7 +102,7 @@
private final List<HighlightInfo> myHighlights = new ArrayList<HighlightInfo>();
protected volatile boolean myHasErrorElement;
- private boolean myErrorFound;
+ private volatile boolean myErrorFound;
private static final Comparator<HighlightVisitor> VISITOR_ORDER_COMPARATOR = new Comparator<HighlightVisitor>() {
@Override
public int compare(final HighlightVisitor o1, final HighlightVisitor o2) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java
index 6b8cfb5..f9488aa 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java
@@ -47,12 +47,10 @@
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.TestOnly;
import java.util.*;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
+import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -519,4 +517,21 @@
public static Throwable getSavedException(DaemonProgressIndicator indicator) {
return indicator.getUserData(THROWABLE_KEY);
}
+
+ @TestOnly
+ public void waitFor(int millis) throws Exception {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ try {
+ for (Job<Void> job : mySubmittedPasses.values()) {
+ if (!job.isDone()) {
+ for (FutureTask task : ((JobImpl)job).getTasks()) {
+ task.get(millis, TimeUnit.MILLISECONDS);
+ }
+ }
+ }
+ }
+ catch (TimeoutException ignored) {
+
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixActionRegistrarImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixActionRegistrarImpl.java
index 56f9745..3890dd4 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixActionRegistrarImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/QuickFixActionRegistrarImpl.java
@@ -22,26 +22,30 @@
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
public class QuickFixActionRegistrarImpl implements QuickFixActionRegistrar {
private final HighlightInfo myInfo;
- public QuickFixActionRegistrarImpl(HighlightInfo info) {
+ public QuickFixActionRegistrarImpl(@Nullable HighlightInfo info) {
myInfo = info;
}
@Override
- public void register(IntentionAction action) {
+ public void register(@NotNull IntentionAction action) {
QuickFixAction.registerQuickFixAction(myInfo, action);
}
@Override
- public void register(TextRange fixRange, IntentionAction action, HighlightDisplayKey key) {
+ public void register(@NotNull TextRange fixRange, @NotNull IntentionAction action, HighlightDisplayKey key) {
QuickFixAction.registerQuickFixAction(myInfo, fixRange, action, key);
}
@Override
- public void unregister(Condition<IntentionAction> condition) {
- QuickFixAction.unregisterQuickFixAction(myInfo, condition);
+ public void unregister(@NotNull Condition<IntentionAction> condition) {
+ if (myInfo != null) {
+ QuickFixAction.unregisterQuickFixAction(myInfo, condition);
+ }
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameFileFix.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameFileFix.java
index e7ff019..6b58579 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameFileFix.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameFileFix.java
@@ -20,7 +20,6 @@
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
@@ -29,7 +28,6 @@
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ex.MessagesEx;
import com.intellij.openapi.vfs.VirtualFile;
@@ -74,7 +72,7 @@
new WriteCommandAction(project) {
@Override
protected void run(Result result) throws Throwable {
- invoke(project, FileEditorManager.getInstance(project).getSelectedTextEditor(), file);
+ invoke(project, null, file);
}
}.execute();
}
@@ -100,12 +98,9 @@
try {
vFile.rename(file.getManager(), myNewFileName);
}
- catch(IOException e){
+ catch (IOException e) {
MessagesEx.error(project, e.getMessage()).showLater();
}
- if (editor != null) {
- DaemonCodeAnalyzer.getInstance(project).updateVisibleHighlighters(editor);
- }
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java
index 1c81a50..0371eb1 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java
@@ -34,6 +34,7 @@
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.ui.content.*;
+import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.update.Activatable;
import com.intellij.util.ui.update.UiNotifyConnector;
import org.jetbrains.annotations.NotNull;
@@ -169,7 +170,12 @@
}
};
- IdeEventQueue.getInstance().addIdleListener(myAutoUpdateRequest, 500);
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ IdeEventQueue.getInstance().addIdleListener(myAutoUpdateRequest, 500);
+ }
+ });
}
}
else {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/generation/actions/GenerateAction.java b/platform/lang-impl/src/com/intellij/codeInsight/generation/actions/GenerateAction.java
index 81e1619..d909be6 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/generation/actions/GenerateAction.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/generation/actions/GenerateAction.java
@@ -24,6 +24,8 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.ListPopup;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
public class GenerateAction extends DumbAwareAction implements PreloadableAction {
@Override
@@ -33,7 +35,7 @@
final ListPopup popup =
JBPopupFactory.getInstance().createActionGroupPopup(
CodeInsightBundle.message("generate.list.popup.title"),
- getGroup(),
+ wrapGroup(getGroup(), dataContext),
dataContext,
JBPopupFactory.ActionSelectionAid.SPEEDSEARCH,
false);
@@ -65,8 +67,56 @@
return (DefaultActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_GENERATE);
}
+ private static DefaultActionGroup wrapGroup(DefaultActionGroup actionGroup, DataContext dataContext) {
+ final DefaultActionGroup copy = new DefaultActionGroup();
+ for (final AnAction action : actionGroup.getChildren(null)) {
+ if (action instanceof GenerateActionPopupTemplateInjector) {
+ final AnAction editTemplateAction = ((GenerateActionPopupTemplateInjector)action).createEditTemplateAction(dataContext);
+ if (editTemplateAction != null) {
+ copy.add(new GenerateWrappingGroup(action, editTemplateAction));
+ continue;
+ }
+ }
+ if (action instanceof DefaultActionGroup) {
+ copy.add(wrapGroup((DefaultActionGroup)action, dataContext));
+ } else {
+ copy.add(action);
+ }
+ }
+ return copy;
+ }
+
@Override
public void preload() {
((ActionManagerImpl) ActionManager.getInstance()).preloadActionGroup(IdeActions.GROUP_GENERATE);
}
+
+ private static class GenerateWrappingGroup extends ActionGroup {
+
+ private final AnAction myAction;
+ private final AnAction myEditTemplateAction;
+
+ public GenerateWrappingGroup(AnAction action, AnAction editTemplateAction) {
+ myAction = action;
+ myEditTemplateAction = editTemplateAction;
+ copyFrom(action);
+ setPopup(true);
+ }
+
+ @Override
+ public boolean canBePerformed(DataContext context) {
+ return true;
+ }
+
+ @NotNull
+ @Override
+ public AnAction[] getChildren(@Nullable AnActionEvent e) {
+ return new AnAction[] {myEditTemplateAction};
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ myAction.actionPerformed(e);
+ }
+ }
}
\ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
index ab4cc84..2e1d2a5 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
@@ -47,7 +47,6 @@
private final OneElementComponent[] myPanels;
private static final Color BACKGROUND_COLOR = HintUtil.INFORMATION_COLOR;
- private static final Color FOREGROUND_COLOR = JBColor.foreground();
private static final Color HIGHLIGHTED_BORDER_COLOR = new JBColor(new Color(231, 254, 234), Gray._100);
private final Font NORMAL_FONT;
private final Font BOLD_FONT;
@@ -338,7 +337,7 @@
myLabel.setBackground(background);
setBackground(background);
- myLabel.setForeground(FOREGROUND_COLOR);
+ myLabel.setForeground(JBColor.foreground());
if (flagsMap.isEmpty()) {
myLabel.setText(XmlStringUtil.wrapInHtml(XmlStringUtil.escapeString(text)));
@@ -347,6 +346,11 @@
String labelText = buildLabelText(text, flagsMap);
myLabel.setText(labelText);
}
+
+ //IDEA-95904 Darcula parameter info pop-up colors hard to read
+ if (UIUtil.isUnderDarcula()) {
+ myLabel.setText(myLabel.getText().replace("<b>", "<b color=ffC800>"));
+ }
}
private String buildLabelText(@NotNull final String text, @NotNull final Map<TextRange, ParameterInfoUIContextEx.Flag> flagsMap) {
final StringBuilder labelText = new StringBuilder(text);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java
index 0d8a17c..8a813b8 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java
@@ -22,12 +22,15 @@
import com.intellij.codeInsight.lookup.RealLookupElementPresentation;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.EditorFontType;
+import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.ui.*;
+import com.intellij.ui.components.JBList;
import com.intellij.ui.speedSearch.SpeedSearchUtil;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.FList;
import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.GraphicsUtil;
@@ -39,6 +42,7 @@
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
/**
* @author peter
@@ -87,11 +91,9 @@
myTailComponent = new MySimpleColoredComponent();
myTailComponent.setIpad(new Insets(0, 0, 0, 0));
- myTailComponent.setFont(myNormalFont);
myTypeLabel = new MySimpleColoredComponent();
myTypeLabel.setIpad(new Insets(0, 0, 0, 0));
- myTypeLabel.setFont(myNormalFont);
myPanel = new LookupPanel();
myPanel.add(myNameComponent, BorderLayout.WEST);
@@ -127,7 +129,11 @@
isSelected ? SELECTED_BACKGROUND_COLOR : BACKGROUND_COLOR;
int allowedWidth = list.getWidth() - AFTER_TAIL - AFTER_TYPE - getIconIndent();
- final LookupElementPresentation presentation = new RealLookupElementPresentation(isSelected ? getMaxWidth() : allowedWidth, myNormalMetrics, myBoldMetrics, myLookup);
+
+ FontMetrics normalMetrics = getRealFontMetrics(item, false);
+ FontMetrics boldMetrics = getRealFontMetrics(item, true);
+ final LookupElementPresentation presentation = new RealLookupElementPresentation(isSelected ? getMaxWidth() : allowedWidth,
+ normalMetrics, boldMetrics, myLookup);
if (item.isValid()) {
item.renderElement(presentation);
} else {
@@ -140,15 +146,20 @@
myNameComponent.setBackground(background);
allowedWidth -= setItemTextLabel(item, new JBColor(isSelected ? SELECTED_FOREGROUND_COLOR : presentation.getItemTextForeground(), foreground), isSelected, presentation, allowedWidth);
+ Font customFont = myLookup.getCustomFont(item, false);
+ myTailComponent.setFont(customFont != null ? customFont : myNormalFont);
+ myTypeLabel.setFont(customFont != null ? customFont : myNormalFont);
+
myTypeLabel.clear();
if (allowedWidth > 0) {
- allowedWidth -= setTypeTextLabel(item, background, foreground, presentation, isSelected ? getMaxWidth() : allowedWidth, isSelected, nonFocusedSelection);
+ allowedWidth -= setTypeTextLabel(item, background, foreground, presentation, isSelected ? getMaxWidth() : allowedWidth, isSelected, nonFocusedSelection, normalMetrics);
}
myTailComponent.clear();
myTailComponent.setBackground(background);
if (isSelected || allowedWidth >= 0) {
- setTailTextLabel(isSelected, presentation, foreground, isSelected ? getMaxWidth() : allowedWidth, nonFocusedSelection);
+ setTailTextLabel(isSelected, presentation, foreground, isSelected ? getMaxWidth() : allowedWidth, nonFocusedSelection,
+ normalMetrics);
}
if (mySelected.containsKey(index)) {
@@ -162,17 +173,20 @@
myTailComponent.getPreferredSize().getWidth() +
myTypeLabel.getPreferredSize().getWidth();
- myPanel.removeAll();
- if (isSelected && w > list.getWidth()) {
- myPanel.setLayout(new BoxLayout(myPanel, BoxLayout.X_AXIS));
- myPanel.add(myNameComponent);
- myPanel.add(myTailComponent);
- myPanel.add(myTypeLabel);
- } else {
- myPanel.setLayout(new BorderLayout());
- myPanel.add(myNameComponent, BorderLayout.WEST);
- myPanel.add(myTailComponent, BorderLayout.CENTER);
- myPanel.add(myTypeLabel, BorderLayout.EAST);
+ boolean useBoxLayout = isSelected && w > list.getWidth() && ((JBList)list).getExpandableItemsHandler().isEnabled();
+ if (useBoxLayout != myPanel.getLayout() instanceof BoxLayout) {
+ myPanel.removeAll();
+ if (useBoxLayout) {
+ myPanel.setLayout(new BoxLayout(myPanel, BoxLayout.X_AXIS));
+ myPanel.add(myNameComponent);
+ myPanel.add(myTailComponent);
+ myPanel.add(myTypeLabel);
+ } else {
+ myPanel.setLayout(new BorderLayout());
+ myPanel.add(myNameComponent, BorderLayout.WEST);
+ myPanel.add(myTailComponent, BorderLayout.CENTER);
+ myPanel.add(myTypeLabel, BorderLayout.EAST);
+ }
}
return myPanel;
@@ -191,7 +205,11 @@
return myMaxWidth;
}
- private void setTailTextLabel(boolean isSelected, LookupElementPresentation presentation, Color foreground, int allowedWidth, boolean nonFocusedSelection) {
+ private void setTailTextLabel(boolean isSelected,
+ LookupElementPresentation presentation,
+ Color foreground,
+ int allowedWidth,
+ boolean nonFocusedSelection, FontMetrics fontMetrics) {
int style = getStyle(false, presentation.isStrikeout(), false);
for (LookupElementPresentation.TextFragment fragment : presentation.getTailFragments()) {
@@ -199,9 +217,9 @@
return;
}
- String trimmed = trimLabelText(fragment.text, allowedWidth, myNormalMetrics);
+ String trimmed = trimLabelText(fragment.text, allowedWidth, fontMetrics);
myTailComponent.append(trimmed, new SimpleTextAttributes(style, getTailTextColor(isSelected, fragment, foreground, nonFocusedSelection)));
- allowedWidth -= RealLookupElementPresentation.getStringWidth(trimmed, myNormalMetrics);
+ allowedWidth -= RealLookupElementPresentation.getStringWidth(trimmed, fontMetrics);
}
}
@@ -269,11 +287,11 @@
private int setItemTextLabel(LookupElement item, final Color foreground, final boolean selected, LookupElementPresentation presentation, int allowedWidth) {
boolean bold = presentation.isItemTextBold();
- myNameComponent.setFont(bold ? myBoldFont : myNormalFont);
-
+ Font customItemFont = myLookup.getCustomFont(item, bold);
+ myNameComponent.setFont(customItemFont != null ? customItemFont : bold ? myBoldFont : myNormalFont);
int style = getStyle(bold, presentation.isStrikeout(), presentation.isItemTextUnderlined());
- final FontMetrics metrics = bold ? myBoldMetrics : myNormalMetrics;
+ final FontMetrics metrics = getRealFontMetrics(item, bold);
final String name = trimLabelText(presentation.getItemText(), allowedWidth, metrics);
int used = RealLookupElementPresentation.getStringWidth(name, metrics);
@@ -281,6 +299,15 @@
return used;
}
+ private FontMetrics getRealFontMetrics(LookupElement item, boolean bold) {
+ Font customFont = myLookup.getCustomFont(item, bold);
+ if (customFont != null) {
+ return myLookup.getEditor().getComponent().getFontMetrics(customFont);
+ }
+
+ return bold ? myBoldMetrics : myNormalMetrics;
+ }
+
@SimpleTextAttributes.StyleAttributeConstant
private static int getStyle(boolean bold, boolean strikeout, boolean underlined) {
int style = bold ? SimpleTextAttributes.STYLE_BOLD : SimpleTextAttributes.STYLE_PLAIN;
@@ -323,11 +350,11 @@
Color foreground,
final LookupElementPresentation presentation,
int allowedWidth,
- boolean selected, boolean nonFocusedSelection) {
+ boolean selected, boolean nonFocusedSelection, FontMetrics normalMetrics) {
final String givenText = presentation.getTypeText();
- final String labelText = trimLabelText(StringUtil.isEmpty(givenText) ? "" : " " + givenText, allowedWidth, myNormalMetrics);
+ final String labelText = trimLabelText(StringUtil.isEmpty(givenText) ? "" : " " + givenText, allowedWidth, normalMetrics);
- int used = RealLookupElementPresentation.getStringWidth(labelText, myNormalMetrics);
+ int used = RealLookupElementPresentation.getStringWidth(labelText, normalMetrics);
final Icon icon = presentation.getTypeIcon();
if (icon != null) {
@@ -346,7 +373,7 @@
sampleBackground = proposedBackground;
}
myTypeLabel.append(" ");
- used += myNormalMetrics.stringWidth("WW");
+ used += normalMetrics.stringWidth("WW");
} else {
myTypeLabel.append(labelText);
}
@@ -371,13 +398,37 @@
return icon;
}
- public int updateMaximumWidth(final LookupElementPresentation p) {
+ @Nullable
+ Font getFontAbleToDisplay(LookupElementPresentation p) {
+ String sampleString = p.getItemText() + p.getTailText() + p.getTypeText();
+
+ // assume a single font can display all lookup item chars
+ Set<Font> fonts = ContainerUtil.newHashSet();
+ for (int i = 0; i < sampleString.length(); i++) {
+ fonts.add(EditorUtil.fontForChar(sampleString.charAt(i), Font.PLAIN, myLookup.getEditor()).getFont());
+ }
+
+ eachFont: for (Font font : fonts) {
+ if (font.equals(myNormalFont)) continue;
+
+ for (int i = 0; i < sampleString.length(); i++) {
+ if (!font.canDisplay(sampleString.charAt(i))) {
+ continue eachFont;
+ }
+ }
+ return font;
+ }
+ return null;
+ }
+
+
+ int updateMaximumWidth(final LookupElementPresentation p, LookupElement item) {
final Icon icon = p.getIcon();
if (icon != null && (icon.getIconWidth() > myEmptyIcon.getIconWidth() || icon.getIconHeight() > myEmptyIcon.getIconHeight())) {
myEmptyIcon = new EmptyIcon(Math.max(icon.getIconWidth(), myEmptyIcon.getIconWidth()), Math.max(icon.getIconHeight(), myEmptyIcon.getIconHeight()));
}
- return RealLookupElementPresentation.calculateWidth(p, myNormalMetrics, myBoldMetrics) + AFTER_TAIL + AFTER_TYPE;
+ return RealLookupElementPresentation.calculateWidth(p, getRealFontMetrics(item, false), getRealFontMetrics(item, true)) + AFTER_TAIL + AFTER_TYPE;
}
public int getIconIndent() {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
index 3f22987..7e09225 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
@@ -17,6 +17,7 @@
package com.intellij.codeInsight.lookup.impl;
import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.completion.CodeCompletionFeatures;
import com.intellij.codeInsight.completion.CompletionLookupArranger;
import com.intellij.codeInsight.completion.PrefixMatcher;
@@ -38,7 +39,6 @@
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.CommandProcessor;
-import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.event.*;
@@ -68,6 +68,7 @@
import com.intellij.util.CollectConsumer;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.ConcurrentHashMap;
+import com.intellij.util.containers.ConcurrentWeakHashMap;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.AbstractLayoutManager;
import com.intellij.util.ui.AsyncProcessIcon;
@@ -139,6 +140,8 @@
private LookupArranger myPresentableArranger;
private final Map<LookupElement, PrefixMatcher> myMatchers = new ConcurrentHashMap<LookupElement, PrefixMatcher>(
ContainerUtil.<LookupElement>identityStrategy());
+ private final Map<LookupElement, Font> myCustomFonts = new ConcurrentWeakHashMap<LookupElement, Font>(
+ ContainerUtil.<LookupElement>identityStrategy());
private LookupHint myElementHint = null;
private final Alarm myHintAlarm = new Alarm();
private final JLabel mySortingLabel = new JLabel();
@@ -337,11 +340,21 @@
public LookupElementPresentation updateLookupWidth(LookupElement item) {
final LookupElementPresentation presentation = renderItemApproximately(item);
- int maxWidth = myCellRenderer.updateMaximumWidth(presentation);
+ final Font customFont = myCellRenderer.getFontAbleToDisplay(presentation);
+ if (customFont != null) {
+ myCustomFonts.put(item, customFont);
+ }
+ int maxWidth = myCellRenderer.updateMaximumWidth(presentation, item);
myLookupTextWidth = Math.max(maxWidth, myLookupTextWidth);
return presentation;
}
+ @Nullable
+ public Font getCustomFont(LookupElement item, boolean bold) {
+ Font font = myCustomFonts.get(item);
+ return font == null ? null : bold ? font.deriveFont(Font.BOLD) : font;
+ }
+
public void requestResize() {
ApplicationManager.getApplication().assertIsDispatchThread();
myResizePending = true;
@@ -570,7 +583,7 @@
}
Rectangle candidate = new Rectangle(location, dim);
ScreenUtil.cropRectangleToFitTheScreen(candidate);
-
+
SwingUtilities.convertPointFromScreen(location, rootPane.getLayeredPane());
return new Rectangle(location.x, location.y, dim.width, candidate.height);
}
@@ -596,7 +609,7 @@
}
final PsiFile file = getPsiFile();
- boolean writableOk = file == null || WriteCommandAction.ensureFilesWritable(myProject, Arrays.asList(file));
+ boolean writableOk = file == null || FileModificationService.getInstance().prepareFileForWrite(file);
if (myDisposed) { // ensureFilesWritable could close us by showing a dialog
return;
}
@@ -676,14 +689,14 @@
EditorModificationUtil.deleteSelectedText(myEditor);
final int caretOffset = myEditor.getCaretModel().getOffset();
int lookupStart = caretOffset - prefix;
-
+
int len = document.getTextLength();
LOG.assertTrue(lookupStart >= 0 && lookupStart <= len,
"ls: " + lookupStart + " caret: " + caretOffset + " prefix:" + prefix + " doc: " + len);
LOG.assertTrue(caretOffset >= 0 && caretOffset <= len, "co: " + caretOffset + " doc: " + len);
document.replaceString(lookupStart, caretOffset, lookupString);
-
+
int offset = lookupStart + lookupString.length();
myEditor.getCaretModel().moveToOffset(offset);
myEditor.getSelectionModel().removeSelection();
@@ -697,7 +710,7 @@
if (item.isCaseSensitive()) {
return lookupString;
}
-
+
final String prefix = itemPattern(item);
final int length = prefix.length();
if (length == 0 || !StringUtil.startsWithIgnoreCase(lookupString, prefix)) return lookupString;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java
index 904c3da..eea5a21 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.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.
@@ -63,6 +63,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
@@ -100,6 +101,8 @@
public class CtrlMouseHandler extends AbstractProjectComponent {
private static final AbstractDocumentationTooltipAction[] ourTooltipActions = {new ShowQuickDocAtPinnedWindowFromTooltipAction()};
+ private static Key<Boolean> ourDebuggerHighlighterKey;
+ private static Key<Boolean> ourXDebuggerHighlighterKey;
private final EditorColorsManager myEditorColorsManager;
private HighlightersSet myHighlighter;
@@ -894,9 +897,11 @@
List<RangeHighlighter> highlighters = new ArrayList<RangeHighlighter>();
TextAttributes attributes = myEditorColorsManager.getGlobalScheme().getAttributes(EditorColors.REFERENCE_HYPERLINK_COLOR);
for (TextRange range : info.getRanges()) {
+ TextAttributes attr = patchAttributesColor(attributes, range, editor, getOrInitDebuggerHighlighterKey());
+ attr = patchAttributesColor(attributes, range, editor, getOrInitXDebuggerHighlighterKey());
final RangeHighlighter highlighter = editor.getMarkupModel().addRangeHighlighter(range.getStartOffset(), range.getEndOffset(),
HighlighterLayer.SELECTION + 1,
- attributes,
+ attr,
HighlighterTargetArea.EXACT_RANGE);
highlighters.add(highlighter);
}
@@ -904,6 +909,43 @@
return new HighlightersSet(highlighters, editor, cursor, info);
}
+
+ /**
+ * Patches attributes to be visible under debugger active line
+ */
+ @SuppressWarnings("UseJBColor")
+ private static TextAttributes patchAttributesColor(TextAttributes attributes, TextRange range, Editor editor, Key<Boolean> key) {
+ if (key != null) {
+ int line = editor.offsetToLogicalPosition(range.getStartOffset()).line;
+ for (RangeHighlighter highlighter : editor.getMarkupModel().getAllHighlighters()) {
+
+ Boolean hasKey = highlighter.getUserData(key);
+ if (hasKey != null && hasKey) {
+ if (editor.offsetToLogicalPosition(highlighter.getStartOffset()).line == line) {
+ TextAttributes clone = attributes.clone();
+ clone.setForegroundColor(Color.orange);
+ clone.setEffectColor(Color.orange);
+ return clone;
+ }
+ }
+ }
+ }
+ return attributes;
+ }
+
+ private static Key<Boolean> getOrInitDebuggerHighlighterKey() {
+ if (ourDebuggerHighlighterKey == null) {
+ ourDebuggerHighlighterKey = Key.findKeyByName("HIGHLIGHTER_USERDATA_KEY");
+ }
+ return ourDebuggerHighlighterKey;
+ }
+ private static Key<Boolean> getOrInitXDebuggerHighlighterKey() {
+ if (ourXDebuggerHighlighterKey == null) {
+ ourXDebuggerHighlighterKey = Key.findKeyByName("EXECUTION_POINT_HIGHLIGHTER_KEY");
+ }
+ return ourXDebuggerHighlighterKey;
+ }
+
private class HighlightersSet {
private final List<RangeHighlighter> myHighlighters;
private final Editor myHighlighterView;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java
index e5c419d..07022bc 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/quickfix/UnresolvedReferenceQuickFixProvider.java
@@ -24,9 +24,7 @@
import org.jetbrains.annotations.NotNull;
public abstract class UnresolvedReferenceQuickFixProvider<T extends PsiReference> {
-
- public static <T extends PsiReference> void registerReferenceFixes(T ref, QuickFixActionRegistrar registrar) {
-
+ public static <T extends PsiReference> void registerReferenceFixes(@NotNull T ref, @NotNull QuickFixActionRegistrar registrar) {
final boolean dumb = DumbService.getInstance(ref.getElement().getProject()).isDumb();
UnresolvedReferenceQuickFixProvider[] fixProviders = Extensions.getExtensions(EXTENSION_NAME);
Class<? extends PsiReference> referenceClass = ref.getClass();
@@ -40,10 +38,9 @@
}
}
- private static final ExtensionPointName<UnresolvedReferenceQuickFixProvider> EXTENSION_NAME =
- ExtensionPointName.create("com.intellij.codeInsight.unresolvedReferenceQuickFixProvider");
+ private static final ExtensionPointName<UnresolvedReferenceQuickFixProvider> EXTENSION_NAME = ExtensionPointName.create("com.intellij.codeInsight.unresolvedReferenceQuickFixProvider");
- public abstract void registerFixes(T ref, QuickFixActionRegistrar registrar);
+ public abstract void registerFixes(@NotNull T ref, @NotNull QuickFixActionRegistrar registrar);
@NotNull
public abstract Class<T> getReferenceClass();
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java
index dc9a918..6daa7bd3 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java
@@ -183,8 +183,7 @@
@Nullable
public TextResult getVariableValue(@NotNull String variableName) {
if (variableName.equals(TemplateImpl.SELECTION)) {
- final String selection = (String)getProperties().get(ExpressionContext.SELECTION);
- return new TextResult(selection == null ? "" : selection);
+ return new TextResult(StringUtil.notNullize(getSelectionBeforeTemplate()));
}
if (variableName.equals(TemplateImpl.END)) {
return new TextResult("");
@@ -207,6 +206,11 @@
}
@Nullable
+ private String getSelectionBeforeTemplate() {
+ return (String)getProperties().get(ExpressionContext.SELECTION);
+ }
+
+ @Nullable
public TextRange getCurrentVariableRange() {
int number = getCurrentSegmentNumber();
if (number == -1) return null;
@@ -838,7 +842,8 @@
}
private void setFinalEditorState() {
- int endSegmentNumber = myTemplate.getEndSegmentNumber();
+ int selectionSegment = myTemplate.getVariableSegmentNumber(TemplateImpl.SELECTION);
+ int endSegmentNumber = selectionSegment >= 0 && getSelectionBeforeTemplate() == null ? selectionSegment : myTemplate.getEndSegmentNumber();
int offset = -1;
if (endSegmentNumber >= 0) {
offset = mySegments.getSegmentStart(endSegmentNumber);
@@ -846,11 +851,6 @@
else {
if (!myTemplate.isSelectionTemplate() && !myTemplate.isInline()) { //do not move caret to the end of range for selection templates
offset = myTemplateRange.getEndOffset();
- } else {
- int selectionSegment = myTemplate.getVariableSegmentNumber(TemplateImpl.SELECTION);
- if (selectionSegment >= 0 && mySegments.getSegmentStart(selectionSegment) == mySegments.getSegmentEnd(selectionSegment)) {
- offset = mySegments.getSegmentStart(selectionSegment);
- }
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java
index 82eb306..7e7024a 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java
@@ -77,7 +77,7 @@
final Presentation presentation = event.getPresentation();
final Project project = event.getData(PlatformDataKeys.PROJECT);
presentation.setEnabled(project != null);
- presentation.setVisible(ActionPlaces.MAIN_MENU.equals(event.getPlace()) && !PlatformUtils.isAppCode());
+ presentation.setVisible(ActionPlaces.MAIN_MENU.equals(event.getPlace()) && !PlatformUtils.isCidr());
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
index 74a162a..74e53ce 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
@@ -653,18 +653,21 @@
myFoldingAlarm.cancelAllRequests();
cancelHeavyAlarm();
}
- CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
- @Override
- public void run() {
- document.setInBulkUpdate(true);
- try {
- document.deleteString(0, document.getTextLength());
+ final int documentTextLength = document.getTextLength();
+ if (documentTextLength > 0) {
+ CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
+ @Override
+ public void run() {
+ document.setInBulkUpdate(true);
+ try {
+ document.deleteString(0, documentTextLength);
+ }
+ finally {
+ document.setInBulkUpdate(false);
+ }
}
- finally {
- document.setInBulkUpdate(false);
- }
- }
- }, null, DocCommandGroupId.noneGroupId(document));
+ }, null, DocCommandGroupId.noneGroupId(document));
+ }
}
@@ -1164,7 +1167,11 @@
@Override
public void update(AnActionEvent e) {
- final boolean enabled = e.getData(LangDataKeys.CONSOLE_VIEW) != null;
+ boolean enabled = e.getData(LangDataKeys.CONSOLE_VIEW) != null;
+ Editor editor = e.getData(PlatformDataKeys.EDITOR);
+ if (editor != null && editor.getDocument().getTextLength() == 0) {
+ enabled = false;
+ }
e.getPresentation().setEnabled(enabled);
}
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ModuleRunConfigurationManager.java b/platform/lang-impl/src/com/intellij/execution/impl/ModuleRunConfigurationManager.java
index 3fe5aaf..2610b38 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/ModuleRunConfigurationManager.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/ModuleRunConfigurationManager.java
@@ -27,8 +27,9 @@
import com.intellij.openapi.module.ModuleComponent;
import com.intellij.openapi.project.ModuleAdapter;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.*;
-import com.intellij.util.containers.ContainerUtil;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
import com.intellij.util.containers.HashSet;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -36,7 +37,6 @@
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -51,24 +51,19 @@
public final class ModuleRunConfigurationManager extends ModuleAdapter implements ModuleComponent, PersistentStateComponent<Element> {
private static final Logger LOG = Logger.getInstance(ModuleRunConfigurationManager.class);
@NonNls static final String COMPONENT_NAME = "ModuleRunConfigurationManager";
- @NotNull
- private final Condition<RunnerAndConfigurationSettings> myModuleConfigCondition = new Condition<RunnerAndConfigurationSettings>() {
- @Override
- public boolean value(@Nullable RunnerAndConfigurationSettings settings) {
- return settings != null && usesMyModule(settings.getConfiguration());
- }
- };
+ final Object myRemoverKey;
@NotNull
private final Module myModule;
@NotNull
- private final RunManagerImpl myManager;
+ final RunManagerImpl myManager;
@Nullable
private List<Element> myUnloadedElements = null;
public ModuleRunConfigurationManager(@NotNull final Module module, @NotNull final RunManagerImpl runManager) {
myModule = module;
myManager = runManager;
+ myRemoverKey = new Object();
}
@Override
@@ -123,11 +118,6 @@
}
}
- @NotNull
- private Collection<? extends RunnerAndConfigurationSettings> getModuleRunConfigurationSettings() {
- return ContainerUtil.filter(myManager.getConfigurationSettings(), myModuleConfigCondition);
- }
-
private boolean usesMyModule(RunConfiguration config) {
return config instanceof ModuleBasedConfiguration
&& myModule.equals(((ModuleBasedConfiguration)config).getConfigurationModule().getModule());
@@ -135,7 +125,7 @@
public void writeExternal(@NotNull final Element element) throws WriteExternalException {
LOG.debug("writeExternal(" + myModule + ")");
- for (final RunnerAndConfigurationSettings settings : getModuleRunConfigurationSettings()) {
+ for (final RunnerAndConfigurationSettings settings : myManager.getExternalSettings(myRemoverKey)) {
myManager.addConfigurationElement(element, settings);
}
if (myUnloadedElements != null) {
@@ -152,7 +142,7 @@
final List children = element.getChildren();
for (final Object child : children) {
- final RunnerAndConfigurationSettings configuration = myManager.loadConfiguration((Element)child, true);
+ final RunnerAndConfigurationSettings configuration = myManager.loadConfiguration(myRemoverKey, (Element)child, true);
if (configuration == null && Comparing.strEqual(element.getName(), RunManagerImpl.CONFIGURATION)) {
if (myUnloadedElements == null) myUnloadedElements = new ArrayList<Element>(2);
myUnloadedElements.add(element);
@@ -178,13 +168,9 @@
}
@Override
- public void beforeModuleRemoved(Project project, Module module) {
- if (!myModule.equals(module)) {
- return;
- }
- LOG.debug("time to remove something from project (" + project + ")");
- for (final RunnerAndConfigurationSettings settings : getModuleRunConfigurationSettings()) {
- myManager.removeConfiguration(settings);
+ public void moduleRemoved(Project project, Module module) {
+ if (myModule.equals(module)) {
+ myManager.removeExternalSettings(myRemoverKey);
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java
index 74ff235..f645686 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java
@@ -49,6 +49,8 @@
new HashMap<String, RunnerAndConfigurationSettings>();
private final Map<String, RunnerAndConfigurationSettings> myConfigurations =
new LinkedHashMap<String, RunnerAndConfigurationSettings>(); // template configurations are not included here
+ final Map<Object, List<RunnerAndConfigurationSettings>> myExternalSettings =
+ new java.util.HashMap<Object, List<RunnerAndConfigurationSettings>>();
private final Map<String, Boolean> mySharedConfigurations = new TreeMap<String, Boolean>();
private final Map<RunConfiguration, List<BeforeRunTask>> myConfigurationToBeforeTasksMap = new WeakHashMap<RunConfiguration, List<BeforeRunTask>>();
@@ -222,6 +224,11 @@
}
@NotNull
+ public List<RunnerAndConfigurationSettings> getExternalSettings(@NotNull Object key) {
+ return myExternalSettings.containsKey(key) ? myExternalSettings.get(key) : Collections.<RunnerAndConfigurationSettings>emptyList();
+ }
+
+ @NotNull
@Override
public List<RunnerAndConfigurationSettings> getAllSettings() {
return Collections.unmodifiableList(new ArrayList<RunnerAndConfigurationSettings>(getSortedConfigurations()));
@@ -233,7 +240,6 @@
for (RunnerAndConfigurationSettings settings : getSortedConfigurations()) {
if (settings.getConfiguration() == configuration) return settings;
}
- LOG.warn("Cannot find settings for RunConfiguration " + configuration.getName());
return null;
}
@@ -397,6 +403,9 @@
@Override
public void removeConfiguration(@Nullable RunnerAndConfigurationSettings settings) {
if (settings == null) return;
+ for (Map.Entry<Object, List<RunnerAndConfigurationSettings>> entry : myExternalSettings.entrySet()) {
+ if (entry.getValue().remove(settings)) break;
+ }
for (Iterator<RunnerAndConfigurationSettings> it = getSortedConfigurations().iterator(); it.hasNext(); ) {
final RunnerAndConfigurationSettings configuration = it.next();
@@ -522,7 +531,7 @@
@Override
public void writeExternal(@NotNull final Element parentNode) throws WriteExternalException {
- writeContext(parentNode);
+ writeContext(parentNode);//writes temporary configurations here
for (final RunnerAndConfigurationSettings runnerAndConfigurationSettings : myTemplateConfigurationsMap.values()) {
if (runnerAndConfigurationSettings.getConfiguration() instanceof UnknownRunConfiguration) {
if (((UnknownRunConfiguration)runnerAndConfigurationSettings.getConfiguration()).isDoNotStore()) {
@@ -777,15 +786,35 @@
fireRunConfigurationsRemoved(configurations);
}
+ public void removeExternalSettings(@NotNull Object removerKey) {
+ List<RunnerAndConfigurationSettings> settingsList = getExternalSettings(removerKey);
+ for (RunnerAndConfigurationSettings each : settingsList) {
+ removeConfiguration(each);
+ }
+ myExternalSettings.remove(removerKey);
+ }
+
@Nullable
public RunnerAndConfigurationSettings loadConfiguration(final Element element, boolean isShared) throws InvalidDataException {
- RunnerAndConfigurationSettingsImpl settings = new RunnerAndConfigurationSettingsImpl(this);
+ return loadConfiguration(null, element, isShared);
+ }
+
+ @Nullable
+ public RunnerAndConfigurationSettings loadConfiguration(@Nullable final Object removerKey, final Element element, boolean isShared) throws InvalidDataException {
+ final RunnerAndConfigurationSettingsImpl settings = new RunnerAndConfigurationSettingsImpl(this);
settings.readExternal(element);
ConfigurationFactory factory = settings.getFactory();
if (factory == null) {
return null;
}
+ if (removerKey !=null) {
+ if (!myExternalSettings.containsKey(removerKey)) {
+ myExternalSettings.put(removerKey, new ArrayList<RunnerAndConfigurationSettings>());
+ }
+ myExternalSettings.get(removerKey).add(settings);
+ }
+
final Element methodsElement = element.getChild(METHOD);
final List<BeforeRunTask> tasks = readStepsBeforeRun(methodsElement, settings);
if (settings.isTemplate()) {
diff --git a/platform/lang-impl/src/com/intellij/execution/runners/RerunTestsAction.java b/platform/lang-impl/src/com/intellij/execution/runners/RerunTestsAction.java
index 5cb729d..901a500 100644
--- a/platform/lang-impl/src/com/intellij/execution/runners/RerunTestsAction.java
+++ b/platform/lang-impl/src/com/intellij/execution/runners/RerunTestsAction.java
@@ -26,6 +26,7 @@
*/
public class RerunTestsAction extends DumbAwareAction implements AnAction.TransparentUpdate {
+ public static final String ID = "RerunTests";
private static final List<RerunInfo> REGISTRY = ContainerUtil.createLockFreeCopyOnWriteList();
public static void register(@NotNull RunContentDescriptor descriptor,
diff --git a/platform/lang-impl/src/com/intellij/execution/runners/RerunTestsNotification.java b/platform/lang-impl/src/com/intellij/execution/runners/RerunTestsNotification.java
new file mode 100644
index 0000000..04f5bdc
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/execution/runners/RerunTestsNotification.java
@@ -0,0 +1,80 @@
+package com.intellij.execution.runners;
+
+import com.intellij.execution.ui.ExecutionConsole;
+import com.intellij.execution.ui.RunContentDescriptor;
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
+import com.intellij.openapi.keymap.KeymapUtil;
+import com.intellij.openapi.ui.popup.Balloon;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.ui.GotItMessage;
+import com.intellij.ui.awt.RelativePoint;
+import com.intellij.util.Alarm;
+import com.intellij.util.ui.update.UiNotifyConnector;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.*;
+
+/**
+* @author Sergey Simonchik
+*/
+public class RerunTestsNotification {
+
+ private static final String KEY = "rerun.tests.notification.shown";
+
+ public static void showRerunNotification(@Nullable RunContentDescriptor contentToReuse,
+ @NotNull final ExecutionConsole executionConsole) {
+ if (contentToReuse == null) {
+ return;
+ }
+ String lastActionId = ActionManagerEx.getInstanceEx().getPrevPreformedActionId();
+ boolean showNotification = !RerunTestsAction.ID.equals(lastActionId);
+ if (showNotification && !PropertiesComponent.getInstance().isTrueValue(KEY)) {
+ UiNotifyConnector.doWhenFirstShown(executionConsole.getComponent(), new Runnable() {
+ @Override
+ public void run() {
+ doShow(executionConsole);
+ }
+ });
+ }
+ }
+
+ private static void doShow(@NotNull final ExecutionConsole executionConsole) {
+ final Alarm alarm = new Alarm();
+ alarm.addRequest(new Runnable() {
+ @Override
+ public void run() {
+ String shortcutText = KeymapUtil.getFirstKeyboardShortcutText(
+ ActionManager.getInstance().getAction(RerunTestsAction.ID)
+ );
+ if (shortcutText.isEmpty()) {
+ return;
+ }
+
+ GotItMessage message = GotItMessage.createMessage("Press " + shortcutText + " to rerun tests", "");
+ message.setDisposable(executionConsole);
+ message.setCallback(new Runnable() {
+ @Override
+ public void run() {
+ PropertiesComponent.getInstance().setValue(KEY, String.valueOf(true));
+ }
+ });
+ message.setShowCallout(false);
+ Dimension consoleSize = executionConsole.getComponent().getSize();
+
+ message.show(
+ new RelativePoint(
+ executionConsole.getComponent(),
+ new Point(consoleSize.width - 185, consoleSize.height - 60)
+ ),
+ Balloon.Position.below
+ );
+
+ Disposer.dispose(alarm);
+ }
+ }, 1000);
+ }
+
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
index b6b24d8..a02e77f 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
@@ -67,7 +67,9 @@
import com.intellij.util.Consumer;
import com.intellij.util.ui.EmptyIcon;
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 javax.swing.border.CompoundBorder;
@@ -171,7 +173,7 @@
}
rebuildList(pattern);
}
- }, 400);
+ }, Registry.intValue("ide.goto.rebuild.delay"));
}
});
editor.addFocusListener(new FocusAdapter() {
@@ -307,7 +309,7 @@
return field;
}
- private static class MySearchTextField extends SearchTextField {
+ private static class MySearchTextField extends SearchTextField implements DataProvider {
public MySearchTextField() {
super(false);
setOpaque(false);
@@ -317,6 +319,15 @@
@Override
protected void showPopup() {
}
+
+ @Nullable
+ @Override
+ public Object getData(@NonNls String dataId) {
+ if (PlatformDataKeys.PREDEFINED_TEXT.is(dataId)) {
+ return getTextEditor().getText();
+ }
+ return null;
+ }
}
private class MyListRenderer extends ColoredListCellRenderer {
diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java
index 4d63f14..9764b18 100644
--- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java
+++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java
@@ -605,7 +605,7 @@
if (helper.supportsFlattenPackages()) {
group.addAction(new FavoritesAbbreviatePackageNamesAction(myProject, myBuilder));
}
- if (!PlatformUtils.isAppCode()) {
+ if (!PlatformUtils.isCidr()) {
group.add(new FavoritesShowMembersAction(myProject, myBuilder));
}
diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java
index 0460ca3..c9cb262 100644
--- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java
@@ -28,6 +28,8 @@
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.options.ShowSettingsUtil;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.Splitter;
@@ -630,4 +632,21 @@
public Runnable enableSearch(String option) {
return null;
}
+
+ public static void editCodeTemplate(@NotNull final String templateId, Project project) {
+ final ShowSettingsUtil util = ShowSettingsUtil.getInstance();
+ final AllFileTemplatesConfigurable configurable = new AllFileTemplatesConfigurable();
+ util.editConfigurable(project, configurable, new Runnable() {
+ @Override
+ public void run() {
+ configurable.myTabbedPane.setSelectedIndex(ArrayUtil.indexOf(configurable.myTabs, configurable.myCodeTemplatesList));
+ for (FileTemplate template : configurable.myCodeTemplatesList.getTemplates()) {
+ if (Comparing.equal(templateId, template.getName())) {
+ configurable.myCodeTemplatesList.selectTemplate(template);
+ break;
+ }
+ }
+ }
+ });
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/ModuleRule.java b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/ModuleRule.java
index 4c34aa3..646e671 100644
--- a/platform/lang-impl/src/com/intellij/ide/impl/dataRules/ModuleRule.java
+++ b/platform/lang-impl/src/com/intellij/ide/impl/dataRules/ModuleRule.java
@@ -21,7 +21,8 @@
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
@@ -40,22 +41,42 @@
Project project = PlatformDataKeys.PROJECT.getData(dataProvider);
if (project == null) {
PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataProvider);
+ if (element == null) {
+ PsiElement[] psiElements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataProvider);
+ if (psiElements != null && psiElements.length > 0) {
+ element = psiElements[0];
+ }
+ }
if (element == null || !element.isValid()) return null;
project = element.getProject();
}
- VirtualFile virtualFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataProvider);
- if (virtualFile == null) {
- GetDataRule dataRule = ((DataManagerImpl)DataManager.getInstance()).getDataRule(PlatformDataKeys.VIRTUAL_FILE.getName());
+ VirtualFile[] files = PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataProvider);
+ if (files == null) {
+ GetDataRule dataRule = ((DataManagerImpl)DataManager.getInstance()).getDataRule(PlatformDataKeys.VIRTUAL_FILE_ARRAY.getName());
if (dataRule != null) {
- virtualFile = (VirtualFile)dataRule.getData(dataProvider);
+ files = (VirtualFile[])dataRule.getData(dataProvider);
}
}
- if (virtualFile == null) {
+ if (files == null) {
return null;
}
- return ModuleUtil.findModuleForFile(virtualFile, project);
+ Module singleModule = null;
+ for (VirtualFile file : files) {
+ Module module = ModuleUtilCore.findModuleForFile(file, project);
+ if (module == null) {
+ return null;
+ }
+ if (singleModule == null) {
+ singleModule = module;
+ }
+ else if (module != singleModule) {
+ return null;
+ }
+ }
+
+ return singleModule;
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java
index 85c2181..de1dcd7 100644
--- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java
+++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java
@@ -521,7 +521,7 @@
return myNodePopup != null && myNodePopup.isVisible();
}
- void navigateInsideBar(final Object object) {
+ protected void navigateInsideBar(final Object object) {
final Object obj = optimizeTarget(object);
myContextObject = null;
diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java
index fb9ac1d..e0c820e 100644
--- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java
+++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.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.
@@ -211,6 +211,9 @@
if (myNavigationBar != null && !Disposer.isDisposed(myNavigationBar)) {
Disposer.dispose(myNavigationBar);
}
+ if (myProject == null) {
+ return;
+ }
myNavigationBar = new NavBarPanel(myProject, true);
myWrapperPanel.putClientProperty("NavBarPanel", myNavigationBar);
myNavigationBar.getModel().setFixedComponent(true);
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java
index e0d1c9c..5760e5b 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java
@@ -394,17 +394,36 @@
content.setSeparator("");
}
}
+
+ String selectID = null;
+ String selectSubID = null;
+
+ // try to find saved selected view...
for (Content content : contents) {
final String id = content.getUserData(ID_KEY);
final String subId = content.getUserData(SUB_ID_KEY);
- if (id != null && id.equals(mySavedPaneId) &&
- StringUtil.equals(subId, content.getUserData(SUB_ID_KEY))) {
- changeView(mySavedPaneId, mySavedPaneSubId);
- mySavedPaneId = null;
- mySavedPaneSubId = null;
+ if (id != null &&
+ id.equals(mySavedPaneId) &&
+ StringUtil.equals(subId, mySavedPaneSubId)) {
+ selectID = id;
+ selectSubID = subId;
break;
}
}
+
+ // saved view not found (plugin disabled, ID changed etc.) - select first available view...
+ if (selectID == null && contents.length > 0) {
+ Content content = contents[0];
+ selectID = content.getUserData(ID_KEY);
+ selectSubID = content.getUserData(SUB_ID_KEY);
+ }
+
+ if (selectID != null) {
+ changeView(selectID, selectSubID);
+ mySavedPaneId = null;
+ mySavedPaneSubId = null;
+ }
+
myUninitializedPanes.clear();
}
@@ -678,7 +697,7 @@
}).setAsSecondary(true);
}
- if (!PlatformUtils.isAppCode()) {
+ if (!PlatformUtils.isCidr()) {
myActionGroup.addAction(new PaneOptionAction(myShowMembers, IdeBundle.message("action.show.members"),
IdeBundle.message("action.show.hide.members"),
AllIcons.ObjectBrowser.ShowMembers, ourShowMembersDefaults))
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java
index c8d3ba2..877d064 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java
@@ -62,7 +62,7 @@
}
protected boolean shouldShowModuleName() {
- return !PlatformUtils.isAppCode();
+ return !PlatformUtils.isCidr();
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiTreeAnchorizer.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiTreeAnchorizer.java
index 1dd3972..aa34383 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiTreeAnchorizer.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiTreeAnchorizer.java
@@ -17,10 +17,12 @@
import com.intellij.ide.util.treeView.TreeAnchorizer;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
-import com.intellij.psi.PsiAnchor;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.SmartPointerManager;
+import com.intellij.psi.SmartPsiElementPointer;
import org.jetbrains.annotations.Nullable;
/**
@@ -28,7 +30,7 @@
*/
public class PsiTreeAnchorizer extends TreeAnchorizer {
- private static final Key<PsiAnchor> PSI_ANCHORIZER_ANCHOR = Key.create("PSI_ANCHORIZER_ANCHOR");
+ private static final Key<SmartPointerWrapper> PSI_ANCHORIZER_POINTER = Key.create("PSI_ANCHORIZER_POINTER");
@Override
public Object createAnchor(Object element) {
@@ -38,15 +40,17 @@
return ApplicationManager.getApplication().runReadAction(new Computable<Object>() {
@Override
public Object compute() {
- PsiAnchor anchor = psiElement.getUserData(PSI_ANCHORIZER_ANCHOR);
+ SmartPointerWrapper pointer = psiElement.getUserData(PSI_ANCHORIZER_POINTER);
if (!psiElement.isValid()) {
- return anchor != null ? anchor : psiElement;
+ return pointer != null ? pointer : psiElement;
}
- if (anchor == null || anchor.retrieve() != psiElement) {
- psiElement.putUserData(PSI_ANCHORIZER_ANCHOR, anchor = PsiAnchor.create(psiElement));
+ if (pointer == null || pointer.myPointer.getElement() != psiElement) {
+ Project project = psiElement.getProject();
+ pointer = new SmartPointerWrapper(SmartPointerManager.getInstance(project).createSmartPsiElementPointer(psiElement));
+ psiElement.putUserData(PSI_ANCHORIZER_POINTER, pointer);
}
- return anchor;
+ return pointer;
}
});
}
@@ -55,14 +59,35 @@
@Override
@Nullable
public Object retrieveElement(Object pointer) {
- if (pointer instanceof PsiAnchor) {
- PsiElement retrieve = ((PsiAnchor)pointer).retrieve();
- if (retrieve == null) {
- //System.out.println("Null anchor: " + pointer);
- }
- return retrieve;
+ if (pointer instanceof SmartPointerWrapper) {
+ return ((SmartPointerWrapper)pointer).myPointer.getElement();
}
return super.retrieveElement(pointer);
}
+
+ private static class SmartPointerWrapper {
+ private final SmartPsiElementPointer myPointer;
+
+ private SmartPointerWrapper(SmartPsiElementPointer pointer) {
+ myPointer = pointer;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SmartPointerWrapper)) return false;
+
+ SmartPointerWrapper wrapper = (SmartPointerWrapper)o;
+
+ if (!myPointer.equals(wrapper.myPointer)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return myPointer.hashCode();
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
index fe1a9f9..9903fbd 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
@@ -70,6 +70,7 @@
import com.intellij.util.Consumer;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.text.Matcher;
import com.intellij.util.text.MatcherHolder;
import com.intellij.util.ui.AsyncProcessIcon;
@@ -153,6 +154,7 @@
private String myFindUsagesTitle;
private ShortcutSet myCheckBoxShortcut;
protected boolean myInitIsDone;
+ static final boolean ourLoadNamesEachTime = FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping;
public boolean checkDisposed() {
if (myDisposedFlag && myPostponedOkAction != null && !myPostponedOkAction.isProcessed()) {
@@ -795,7 +797,10 @@
}
}
- if (index == 1 && myModel instanceof ContributorsBasedGotoByModel && myNames[0] != null) {
+ if (index == 1 &&
+ myModel instanceof ContributorsBasedGotoByModel &&
+ ((ContributorsBasedGotoByModel)myModel).sameNamesForProjectAndLibraries() &&
+ myNames[0] != null) {
// there is no way in indices to have different keys for project symbols vs libraries, we always have same ones
myNames[1] = myNames[0];
return;
@@ -814,6 +819,10 @@
@NotNull
public String[] getNames(boolean checkboxState) {
+ if (ourLoadNamesEachTime) {
+ myNames[checkboxState ? 1 : 0] = null;
+ ensureNamesLoaded(checkboxState);
+ }
return checkboxState ? myNames[1] : myNames[0];
}
@@ -1193,8 +1202,9 @@
}
final String text = myTextField.getText();
+ if (text.length() == 0) return Collections.emptyList();
final boolean checkBoxState = myCheckBox.isSelected();
- //ensureNamesLoaded(checkBoxState);
+ if (ourLoadNamesEachTime) ensureNamesLoaded(checkBoxState);
final String[] names = checkBoxState ? myNames[1] : myNames[0];
if (names == null) return Collections.emptyList();
@@ -1489,7 +1499,7 @@
public void run() {
try {
boolean everywhere = myCheckboxState;
- ensureNamesLoaded(everywhere);
+ if (!ourLoadNamesEachTime) ensureNamesLoaded(everywhere);
addElementsByPattern(myPattern, elements, myCancelled, everywhere);
}
catch (ProcessCanceledException e) {
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java
index 1fc318a..b98d2e4 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java
@@ -20,6 +20,7 @@
import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.util.NavigationItemListCellRenderer;
import com.intellij.navigation.ChooseByNameContributor;
+import com.intellij.navigation.EfficientChooseByNameContributor;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.application.ReadActionProcessor;
import com.intellij.openapi.diagnostic.Logger;
@@ -32,9 +33,12 @@
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
+import com.intellij.util.containers.ConcurrentHashMap;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
+import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -47,7 +51,7 @@
/**
* Contributor-based goto model
*/
-public abstract class ContributorsBasedGotoByModel implements ChooseByNameModel {
+public abstract class ContributorsBasedGotoByModel implements EfficientChooseByNameModel {
public static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.gotoByName.ContributorsBasedGotoByModel");
protected final Project myProject;
@@ -74,11 +78,14 @@
};
}
- @NotNull
- @Override
- public String[] getNames(final boolean checkBoxState) {
- final THashSet<String> allNames = ContainerUtil.newTroveSet();
+ public boolean sameNamesForProjectAndLibraries() {
+ return !ChooseByNameBase.ourLoadNamesEachTime;
+ }
+ private final ConcurrentHashMap<ChooseByNameContributor, TIntHashSet> myContributorToItsSymbolsMap = new ConcurrentHashMap<ChooseByNameContributor, TIntHashSet>();
+
+ @Override
+ public void processNames(final Processor<String> nameProcessor, final boolean checkBoxState) {
long start = System.currentTimeMillis();
List<ChooseByNameContributor> liveContribs = filterDumb(myContributors);
ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
@@ -87,10 +94,30 @@
public boolean processInReadAction(ChooseByNameContributor contributor) {
try {
if (!myProject.isDisposed()) {
- String[] names = contributor.getNames(myProject, checkBoxState);
- synchronized (allNames) {
- allNames.ensureCapacity(names.length);
- ContainerUtil.addAll(allNames, names);
+ long contributorStarted = System.currentTimeMillis();
+ final TIntHashSet filter = new TIntHashSet(1000);
+ myContributorToItsSymbolsMap.put(contributor, filter);
+ if (contributor instanceof EfficientChooseByNameContributor) {
+ ((EfficientChooseByNameContributor)contributor).processNames(new Processor<String>() {
+ @Override
+ public boolean process(String s) {
+ if (nameProcessor.process(s)) {
+ filter.add(s.hashCode());
+ }
+ return true;
+ }
+ }, DefaultFileNavigationContributor.getScope(myProject, checkBoxState), DefaultFileNavigationContributor.getFilter(myProject, checkBoxState));
+ } else {
+ String[] names = contributor.getNames(myProject, checkBoxState);
+ for (String element : names) {
+ if (nameProcessor.process(element)) {
+ filter.add(element.hashCode());
+ }
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(contributor + " for " + (System.currentTimeMillis() - contributorStarted));
}
}
}
@@ -114,7 +141,18 @@
}
long finish = System.currentTimeMillis();
if (LOG.isDebugEnabled()) {
- LOG.debug("getNames(): "+(finish-start)+"ms; (got "+allNames.size()+" elements)");
+ LOG.debug("processNames(): "+(finish-start)+"ms;");
+ }
+ }
+
+ @NotNull
+ @Override
+ public String[] getNames(final boolean checkBoxState) {
+ final THashSet<String> allNames = ContainerUtil.newTroveSet();
+
+ processNames(new CommonProcessors.CollectProcessor<String>(allNames), checkBoxState);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("getNames(): (got "+allNames.size()+" elements)");
}
return ArrayUtil.toStringArray(allNames);
}
@@ -133,6 +171,7 @@
@NotNull
public Object[] getElementsByName(final String name, final boolean checkBoxState, final String pattern, @NotNull final ProgressIndicator canceled) {
+ long elementByNameStarted = System.currentTimeMillis();
final List<NavigationItem> items = Collections.synchronizedList(new ArrayList<NavigationItem>());
Processor<ChooseByNameContributor> processor = new Processor<ChooseByNameContributor>() {
@@ -141,8 +180,12 @@
if (myProject.isDisposed()) {
return true;
}
+ TIntHashSet filter = myContributorToItsSymbolsMap.get(contributor);
+ if (!filter.contains(name.hashCode())) return true;
try {
- for (NavigationItem item : contributor.getItemsByName(name, pattern, myProject, checkBoxState)) {
+ long contributorStarted = System.currentTimeMillis();
+ NavigationItem[] itemsByName = contributor.getItemsByName(name, pattern, myProject, checkBoxState);
+ for (NavigationItem item : itemsByName) {
canceled.checkCanceled();
if (item == null) {
PluginId pluginId = PluginManager.getPluginByClassName(contributor.getClass().getName());
@@ -159,6 +202,10 @@
items.add(item);
}
}
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(System.currentTimeMillis() - contributorStarted + "," + contributor + "," + itemsByName.length);
+ }
}
catch (ProcessCanceledException ex) {
// index corruption detected, ignore
@@ -173,6 +220,9 @@
canceled.cancel();
}
canceled.checkCanceled(); // if parallel job execution was canceled because of PCE, rethrow it from here
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Retrieving " + name + ":" + items.size() + " for " + (System.currentTimeMillis() - elementByNameStarted));
+ }
return ArrayUtil.toObjectArray(items);
}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java
index 00de48d..d3dfe99 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java
@@ -47,11 +47,11 @@
}
@Override
- public boolean filterElements(@NotNull ChooseByNameBase base,
- @NotNull String pattern,
+ public boolean filterElements(@NotNull final ChooseByNameBase base,
+ @NotNull final String pattern,
boolean everywhere,
@NotNull ProgressIndicator indicator,
- @NotNull Processor<Object> consumer) {
+ @NotNull final Processor<Object> consumer) {
String namePattern = getNamePattern(base, pattern);
String qualifierPattern = getQualifierPattern(base, pattern);
@@ -60,13 +60,46 @@
final ChooseByNameModel model = base.getModel();
String matchingPattern = convertToMatchingPattern(base, namePattern);
List<MatchResult> namesList = new ArrayList<MatchResult>();
- String[] names = base.getNames(everywhere);
- CollectConsumer<MatchResult> collect = new SynchronizedCollectConsumer<MatchResult>(namesList);
- processNamesByPattern(base, names, matchingPattern, indicator, collect);
+
+ final CollectConsumer<MatchResult> collect = new SynchronizedCollectConsumer<MatchResult>(namesList);
+ long started;
+
+ if (model instanceof EfficientChooseByNameModel) {
+ indicator.checkCanceled();
+ started = System.currentTimeMillis();
+ final MinusculeMatcher matcher = buildPatternMatcher(matchingPattern, NameUtil.MatchingCaseSensitivity.NONE);
+ ((EfficientChooseByNameModel)model).processNames(new Processor<String>() {
+ @Override
+ public boolean process(String sequence) {
+ ProgressManager.checkCanceled();
+ MatchResult result = matches(base, pattern, matcher, sequence);
+ if (result != null) {
+ collect.consume(result);
+ return true;
+ }
+ return false;
+ }
+ }, everywhere);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("loaded + matched:"+ (System.currentTimeMillis() - started)+ "," + collect.getResult().size());
+ }
+ } else {
+ String[] names = base.getNames(everywhere);
+ started = System.currentTimeMillis();
+ processNamesByPattern(base, names, matchingPattern, indicator, collect);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("matched:"+ (System.currentTimeMillis() - started)+ "," + names.length);
+ }
+ }
indicator.checkCanceled();
- sortNamesList(matchingPattern, (List<MatchResult>)collect.getResult());
+ started = System.currentTimeMillis();
+ List<MatchResult> results = (List<MatchResult>)collect.getResult();
+ sortNamesList(matchingPattern, results);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("sorted:"+ (System.currentTimeMillis() - started) + ",results:" + results.size());
+ }
indicator.checkCanceled();
List<Object> sameNameElements = new SmartList<Object>();
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultFileNavigationContributor.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultFileNavigationContributor.java
index 7b0e73b..4c796da 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultFileNavigationContributor.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultFileNavigationContributor.java
@@ -16,21 +16,83 @@
package com.intellij.ide.util.gotoByName;
import com.intellij.navigation.ChooseByNameContributor;
+import com.intellij.navigation.EfficientChooseByNameContributor;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ContentIterator;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileWithId;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.ProjectScope;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Processor;
+import com.intellij.util.indexing.FileBasedIndex;
+import com.intellij.util.indexing.FileBasedIndexImpl;
+import com.intellij.util.indexing.IdFilter;
+import gnu.trove.THashSet;
+import gnu.trove.TIntArrayList;
+import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
-public class DefaultFileNavigationContributor implements ChooseByNameContributor, DumbAware {
+import java.util.BitSet;
+
+public class DefaultFileNavigationContributor implements EfficientChooseByNameContributor, DumbAware {
@Override
@NotNull
public String[] getNames(Project project, boolean includeNonProjectItems) {
- return FilenameIndex.getAllFilenames(project);
+ if (FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping) {
+ final THashSet<String> names = new THashSet<String>(1000);
+ IdFilter filter = getFilter(project, includeNonProjectItems);
+ processNames(new Processor<String>() {
+ @Override
+ public boolean process(String s) {
+ names.add(s);
+ return true;
+ }
+ }, getScope(project, includeNonProjectItems), filter);
+ System.out.println("All names retrieved2:" + names.size());
+ return ArrayUtil.toStringArray(names);
+ } else {
+ return FilenameIndex.getAllFilenames(project);
+ }
+ }
+
+ public static GlobalSearchScope getScope(Project project, boolean includeNonProjectItems) {
+ return includeNonProjectItems ? GlobalSearchScope.projectScope(project) : GlobalSearchScope.allScope(project);
+ }
+
+ public static IdFilter getFilter(Project project, boolean includeNonProjectItems) {
+ long started = System.currentTimeMillis();
+ final BitSet idSet = new BitSet();
+
+ ContentIterator iterator = new ContentIterator() {
+ @Override
+ public boolean processFile(VirtualFile fileOrDir) {
+ idSet.set(
+ ((VirtualFileWithId)fileOrDir).getId()
+ );
+ return true;
+ }
+ };
+
+ if (!includeNonProjectItems) {
+ ProjectRootManager.getInstance(project).getFileIndex().iterateContent(iterator);
+ } else {
+ FileBasedIndex.getInstance().iterateIndexableFiles(iterator, project, null);
+ }
+
+ System.out.println("Done filter " + (System.currentTimeMillis() -started) + ":" + idSet.size());
+ return new IdFilter() {
+ @Override
+ public boolean contains(int id) {
+ return idSet.get(id);
+ }
+ };
}
@Override
@@ -48,4 +110,16 @@
}
return items;
}
+
+ @Override
+ public void processNames(final Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
+ long started = System.currentTimeMillis();
+ FileBasedIndex.getInstance().processAllKeys(FilenameIndex.NAME, new Processor<String>() {
+ @Override
+ public boolean process(String s) {
+ return processor.process(s);
+ }
+ }, scope, filter);
+ System.out.println("All names retrieved:" + (System.currentTimeMillis() - started));
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/EfficientChooseByNameModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/EfficientChooseByNameModel.java
new file mode 100644
index 0000000..c50d347
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/EfficientChooseByNameModel.java
@@ -0,0 +1,22 @@
+/*
+ * 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.util.gotoByName;
+
+import com.intellij.util.Processor;
+
+public interface EfficientChooseByNameModel extends ChooseByNameModel {
+ void processNames(Processor<String> processor, boolean inLibraries);
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoClassModel2.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoClassModel2.java
index 329c190..8d80a1c 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoClassModel2.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoClassModel2.java
@@ -22,9 +22,11 @@
import com.intellij.navigation.ChooseByNameRegistry;
import com.intellij.navigation.GotoClassContributor;
import com.intellij.navigation.NavigationItem;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.psi.PsiElement;
+import com.intellij.util.indexing.FileBasedIndex;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -146,4 +148,9 @@
public boolean willOpenEditor() {
return true;
}
+
+ @Override
+ public boolean sameNamesForProjectAndLibraries() {
+ return !FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping;
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileModel.java
index adc943ea..82ecacb 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileModel.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileModel.java
@@ -30,6 +30,7 @@
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
+import com.intellij.util.indexing.FileBasedIndex;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -115,6 +116,11 @@
}
@Override
+ public boolean sameNamesForProjectAndLibraries() {
+ return !FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping;
+ }
+
+ @Override
@Nullable
public String getFullName(final Object element) {
if (element instanceof PsiFileSystemItem) {
diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
index 8abcde7..f594893 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
@@ -237,7 +237,7 @@
result.add(GlobalSearchScope.allScope(project));
}
- if (!PlatformUtils.isAppCode()) { // TODO: fix these scopes in AppCode
+ if (!PlatformUtils.isCidr()) { // TODO: fix these scopes in AppCode
result.add(GlobalSearchScopes.projectProductionScope(project));
result.add(GlobalSearchScopes.projectTestScope(project));
}
@@ -250,7 +250,7 @@
dataContextElement = LangDataKeys.PSI_ELEMENT.getData(dataContext);
}
if (dataContextElement != null) {
- if (!PlatformUtils.isAppCode()) { // TODO: have an API to disable module scopes.
+ if (!PlatformUtils.isCidr()) { // TODO: have an API to disable module scopes.
Module module = ModuleUtilCore.findModuleForPsiElement(dataContextElement);
if (module == null) {
module = LangDataKeys.MODULE.getData(dataContext);
diff --git a/platform/lang-impl/src/com/intellij/navigation/EfficientChooseByNameContributor.java b/platform/lang-impl/src/com/intellij/navigation/EfficientChooseByNameContributor.java
new file mode 100644
index 0000000..d70bd7a
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/navigation/EfficientChooseByNameContributor.java
@@ -0,0 +1,25 @@
+/*
+ * 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.navigation;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.Processor;
+import com.intellij.util.indexing.IdFilter;
+
+public interface EfficientChooseByNameContributor extends ChooseByNameContributor {
+ void processNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter);
+}
diff --git a/platform/lang-impl/src/com/intellij/openapi/diff/impl/settings/DiffOptionsPanel.java b/platform/lang-impl/src/com/intellij/openapi/diff/impl/settings/DiffOptionsPanel.java
index d661a65..74e47bd 100644
--- a/platform/lang-impl/src/com/intellij/openapi/diff/impl/settings/DiffOptionsPanel.java
+++ b/platform/lang-impl/src/com/intellij/openapi/diff/impl/settings/DiffOptionsPanel.java
@@ -28,6 +28,7 @@
import com.intellij.util.EventDispatcher;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
@@ -35,7 +36,10 @@
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.*;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
public class DiffOptionsPanel implements OptionsPanel {
private final ColorAndFontOptions myOptions;
@@ -242,7 +246,7 @@
return myStripeMarkColorComponent.getComponent();
}
- public static void addSchemeDescriptions(ArrayList<EditorSchemeAttributeDescriptor> descriptions, EditorColorsScheme scheme) {
+ public static void addSchemeDescriptions(@NotNull List<EditorSchemeAttributeDescriptor> descriptions, @NotNull EditorColorsScheme scheme) {
for (TextDiffType diffType : TextDiffType.MERGE_TYPES) {
descriptions.add(new MyColorAndFontDescription(diffType, scheme));
}
@@ -265,7 +269,7 @@
private final EditorColorsScheme myScheme;
private final TextDiffType myDiffType;
- public MyColorAndFontDescription(TextDiffType diffType, EditorColorsScheme scheme) {
+ public MyColorAndFontDescription(@NotNull TextDiffType diffType, @NotNull EditorColorsScheme scheme) {
myScheme = scheme;
myDiffType = diffType;
TextAttributes attrs = diffType.getTextAttributes(myScheme);
diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ui/DirectoryNode.java b/platform/lang-impl/src/com/intellij/packageDependencies/ui/DirectoryNode.java
index 145624c..7464c9f 100644
--- a/platform/lang-impl/src/com/intellij/packageDependencies/ui/DirectoryNode.java
+++ b/platform/lang-impl/src/com/intellij/packageDependencies/ui/DirectoryNode.java
@@ -170,9 +170,9 @@
public PsiDirectory getTargetDirectory() {
DirectoryNode dirNode = this;
- while (dirNode.getCompactedDirNode() != null) {
- dirNode = dirNode.getCompactedDirNode();
- assert dirNode != null;
+ DirectoryNode compacted;
+ while ((compacted = dirNode.getCompactedDirNode()) != null) {
+ dirNode = compacted;
}
return dirNode.getPsiDirectory();
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java
index 62d1cb0..cfe75941 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java
@@ -99,12 +99,11 @@
final VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document);
if (virtualFile != null && virtualFile.isValid()) {
Collection<Project> projects = ProjectLocator.getInstance().getProjectsForFile(virtualFile);
- LOG.assertTrue(projects.isEmpty() || projects.contains(myProject), "Trying to get PSI for an alien project. VirtualFile=" +
- virtualFile +
- ";\n myProject=" +
- myProject +
- ";\n projects returned: " +
- projects);
+ if (!projects.isEmpty() && !projects.contains(myProject)) {
+ LOG.error("Trying to get PSI for an alien project. VirtualFile=" + virtualFile +
+ ";\n myProject=" + myProject +
+ ";\n projects returned: " + projects);
+ }
}
}
return psiFile;
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java
index 9d7a9e9..af96331 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java
@@ -19,6 +19,7 @@
import com.intellij.lang.ASTNode;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationAdapter;
import com.intellij.openapi.application.ApplicationListener;
import com.intellij.openapi.application.ApplicationManager;
@@ -53,6 +54,7 @@
import org.jetbrains.annotations.TestOnly;
import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
public class PostprocessReformattingAspect implements PomModelAspect {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PostprocessReformattingAspect");
@@ -62,8 +64,9 @@
private final Map<FileViewProvider, List<ASTNode>> myReformatElements = new HashMap<FileViewProvider, List<ASTNode>>();
private volatile int myDisabledCounter = 0;
private final Set<FileViewProvider> myUpdatedProviders = new HashSet<FileViewProvider>();
+ private final AtomicInteger myPostponedCounter = new AtomicInteger();
- public PostprocessReformattingAspect(Project project, PsiManager psiManager, TreeAspect treeAspect) {
+ public PostprocessReformattingAspect(Project project, PsiManager psiManager, TreeAspect treeAspect,final CommandProcessor processor) {
myProject = project;
myPsiManager = psiManager;
myTreeAspect = treeAspect;
@@ -73,18 +76,16 @@
ApplicationListener applicationListener = new ApplicationAdapter() {
@Override
public void writeActionStarted(final Object action) {
- final CommandProcessor processor = CommandProcessor.getInstance();
if (processor != null) {
final Project project = processor.getCurrentCommandProject();
if (project == myProject) {
- myPostponedCounter++;
+ incrementPostponedCounter();
}
}
}
@Override
public void writeActionFinished(final Object action) {
- final CommandProcessor processor = CommandProcessor.getInstance();
if (processor != null) {
final Project project = processor.getCurrentCommandProject();
if (project == myProject) {
@@ -117,8 +118,6 @@
}
}
- private int myPostponedCounter = 0;
-
public void postponeFormattingInside(final Runnable runnable) {
postponeFormattingInside(new NullableComputable<Object>() {
@Override
@@ -130,9 +129,10 @@
}
public <T> T postponeFormattingInside(Computable<T> computable) {
+ Application application = ApplicationManager.getApplication();
+ application.assertIsDispatchThread();
try {
- //if(myPostponedCounter == 0) myDisabled = false;
- myPostponedCounter++;
+ incrementPostponedCounter();
return computable.compute();
}
finally {
@@ -140,13 +140,19 @@
}
}
+ private void incrementPostponedCounter() {
+ myPostponedCounter.incrementAndGet();
+ }
+
private void decrementPostponedCounter() {
- if (--myPostponedCounter == 0) {
- if (ApplicationManager.getApplication().isWriteAccessAllowed()) {
+ Application application = ApplicationManager.getApplication();
+ application.assertIsDispatchThread();
+ if (myPostponedCounter.decrementAndGet() == 0) {
+ if (application.isWriteAccessAllowed()) {
doPostponedFormatting();
}
else {
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ application.runWriteAction(new Runnable() {
@Override
public void run() {
doPostponedFormatting();
@@ -156,7 +162,7 @@
}
}
- private static void atomic(Runnable r) {
+ private static void atomic(@NotNull Runnable r) {
ProgressManager.getInstance().executeNonCancelableSection(r);
}
@@ -165,7 +171,7 @@
atomic(new Runnable() {
@Override
public void run() {
- if (isDisabled() || myPostponedCounter == 0 && !ApplicationManager.getApplication().isUnitTestMode()) return;
+ if (isDisabled() || myPostponedCounter.get() == 0 && !ApplicationManager.getApplication().isUnitTestMode()) return;
final TreeChangeEvent changeSet = (TreeChangeEvent)event.getChangeSet(myTreeAspect);
if (changeSet == null) return;
final PsiElement psiElement = changeSet.getRootElement().getPsi();
@@ -287,8 +293,6 @@
}
private void doPostponedFormattingInner(final FileViewProvider key) {
-
-
final List<ASTNode> astNodes = myReformatElements.remove(key);
final Document document = key.getDocument();
// Sort ranges by end offsets so that we won't need any offset adjustment after reformat or reindent
@@ -307,7 +311,7 @@
// then we create ranges by changed nodes. One per node. There ranges can intersect. Ranges are sorted by end offset.
if (astNodes != null) createActionsMap(astNodes, key, postProcessTasks);
- if ("true".equals(System.getProperty("check.psi.is.valid")) && ApplicationManager.getApplication().isUnitTestMode()) {
+ if (Boolean.getBoolean("check.psi.is.valid") && ApplicationManager.getApplication().isUnitTestMode()) {
checkPsiIsCorrect(key);
}
@@ -316,7 +320,7 @@
// (free reformatting -> reindent -> formatting under reindent)
final List<PostponedAction> normalizedActions = normalizeAndReorderPostponedActions(postProcessTasks, document);
toDispose.addAll(normalizedActions);
-
+
// only in following loop real changes in document are made
for (final PostponedAction normalizedAction : normalizedActions) {
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(myPsiManager.getProject());
@@ -649,6 +653,7 @@
return myRange.getEndOffset();
}
+ @Override
public void dispose() {
if (myRange.isValid()) {
myRange.dispose();
diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java
index 744f910..7b5f9ff 100644
--- a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java
@@ -142,7 +142,9 @@
IndexInfrastructure.getStorageFile(indexKey),
extension.getKeyDescriptor(),
new StubIdExternalizer(),
- extension.getCacheSize()
+ extension.getCacheSize(),
+ false,
+ extension instanceof StringStubIndexExtension && ((StringStubIndexExtension)extension).traceKeyHashToVirtualFileMapping()
);
final MemoryIndexStorage<K, StubIdList> memStorage = new MemoryIndexStorage<K, StubIdList>(storage);
@@ -285,11 +287,16 @@
@Override
public <K> boolean processAllKeys(@NotNull StubIndexKey<K, ?> indexKey, @NotNull Project project, Processor<K> processor) {
- FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, GlobalSearchScope.allScope(project));
+ return processAllKeys(indexKey, processor, GlobalSearchScope.allScope(project), null);
+ }
+
+ public <K> boolean processAllKeys(@NotNull StubIndexKey<K, ?> indexKey, Processor<K> processor, GlobalSearchScope scope, @Nullable IdFilter idFilter) {
+
+ FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, scope.getProject(), scope);
final MyIndex<K> index = (MyIndex<K>)myIndices.get(indexKey);
try {
- return index.processAllKeys(processor);
+ return index.processAllKeys(processor, idFilter);
}
catch (StorageException e) {
forceRebuild(e);
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenameHandler.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenameHandler.java
index 8f31703..1b4a4c2 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenameHandler.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenameHandler.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.
@@ -40,12 +40,16 @@
public class MemberInplaceRenameHandler extends VariableInplaceRenameHandler {
@Override
protected boolean isAvailable(PsiElement element, Editor editor, PsiFile file) {
- final PsiElement nameSuggestionContext = file.findElementAt(editor.getCaretModel().getOffset());
+ PsiElement nameSuggestionContext = file.findElementAt(editor.getCaretModel().getOffset());
+ if (nameSuggestionContext == null && editor.getCaretModel().getOffset() > 0) {
+ nameSuggestionContext = file.findElementAt(editor.getCaretModel().getOffset() - 1);
+ }
+
if (element == null && LookupManager.getActiveLookup(editor) != null) {
element = PsiTreeUtil.getParentOfType(nameSuggestionContext, PsiNamedElement.class);
}
final RefactoringSupportProvider
- supportProvider = element != null ? LanguageRefactoringSupport.INSTANCE.forLanguage(element.getLanguage()) : null;
+ supportProvider = element == null ? null : LanguageRefactoringSupport.INSTANCE.forLanguage(element.getLanguage());
return editor.getSettings().isVariableInplaceRenameEnabled()
&& supportProvider != null
&& supportProvider.isMemberInplaceRenameAvailable(element, nameSuggestionContext);
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenameHandler.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenameHandler.java
index 0892f1e..ccdb0b0 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenameHandler.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenameHandler.java
@@ -54,8 +54,8 @@
protected boolean isAvailable(PsiElement element, Editor editor, PsiFile file) {
final PsiElement nameSuggestionContext = file.findElementAt(editor.getCaretModel().getOffset());
- final RefactoringSupportProvider
- supportProvider = element != null ? LanguageRefactoringSupport.INSTANCE.forLanguage(element.getLanguage()):null;
+ RefactoringSupportProvider supportProvider =
+ element == null ? null : LanguageRefactoringSupport.INSTANCE.forLanguage(element.getLanguage());
return supportProvider != null &&
editor.getSettings().isVariableInplaceRenameEnabled() &&
supportProvider.isInplaceRenameAvailable(element, nameSuggestionContext);
diff --git a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java
index 2591fef..4e70241 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java
@@ -435,7 +435,7 @@
return super.isToBeChanged(usageInfo);
}
- public static boolean validElement(PsiElement element) {
+ public static boolean validElement(@NotNull PsiElement element) {
if (element instanceof PsiFile) return true;
if (!element.isPhysical()) return false;
final RefactoringSupportProvider provider = LanguageRefactoringSupport.INSTANCE.forLanguage(element.getLanguage());
diff --git a/platform/lang-impl/src/com/intellij/ui/LanguageTextField.java b/platform/lang-impl/src/com/intellij/ui/LanguageTextField.java
index a55f4e90..9074e74 100644
--- a/platform/lang-impl/src/com/intellij/ui/LanguageTextField.java
+++ b/platform/lang-impl/src/com/intellij/ui/LanguageTextField.java
@@ -32,18 +32,23 @@
public class LanguageTextField extends EditorTextField {
private final Language myLanguage;
+ // Could be null to allow usage in UI designer, as EditorTextField permits
private final Project myProject;
- public LanguageTextField(Language language, @NotNull Project project, @NotNull String value) {
+ public LanguageTextField() {
+ this(null, null, "");
+ }
+
+ public LanguageTextField(Language language, @Nullable Project project, @NotNull String value) {
this(language, project, value, true);
}
- public LanguageTextField(Language language, @NotNull Project project, @NotNull String value, boolean oneLineMode) {
+ public LanguageTextField(Language language, @Nullable Project project, @NotNull String value, boolean oneLineMode) {
this(language, project, value, new SimpleDocumentCreator(), oneLineMode);
}
public LanguageTextField(@Nullable Language language,
- @NotNull Project project,
+ @Nullable Project project,
@NotNull String value,
@NotNull DocumentCreator documentCreator)
{
@@ -51,7 +56,7 @@
}
public LanguageTextField(@Nullable Language language,
- @NotNull Project project,
+ @Nullable Project project,
@NotNull String value,
@NotNull DocumentCreator documentCreator,
boolean oneLineMode) {
diff --git a/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletion.java b/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletion.java
index f17beff..2690a2a 100644
--- a/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletion.java
+++ b/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletion.java
@@ -36,45 +36,57 @@
import java.util.Collection;
/**
+ * <p/>
+ * It is text field with autocompletion from list of values.
+ * <p/>
+ * Autocompletion is implemented via {@code TextFieldWithAutoCompletionContributor}.
+ * Use {@code setVariants} set list of values for autocompletion.
+ *
* @author Roman Chernyatchik
- * <p/>
- * It is text field with autocompletion from list of values.
- * <p/>
- * Autocompletion is implemented via LookupManager.
- * Use setVariants(..) set list of values for autocompletion.
- * For variants you can use not only instances of PresentableLookupValue, but
- * also instances of LookupValueWithPriority and LookupValueWithUIHint
*/
public class TextFieldWithAutoCompletion<T> extends LanguageTextField {
public static final TextFieldWithAutoCompletionListProvider EMPTY_COMPLETION = new StringsCompletionProvider(null, null);
private final boolean myShowAutocompletionIsAvailableHint;
+ private final TextFieldWithAutoCompletionListProvider<T> myProvider;
+ @SuppressWarnings("unchecked")
public TextFieldWithAutoCompletion() {
- // For UI designer
- this(null, null, false, null);
+ this(null, EMPTY_COMPLETION, false, null);
}
+
public TextFieldWithAutoCompletion(final Project project,
- @Nullable final TextFieldWithAutoCompletionListProvider<T> provider,
+ @NotNull final TextFieldWithAutoCompletionListProvider<T> provider,
final boolean showAutocompletionIsAvailableHint, @Nullable final String text) {
super(PlainTextLanguage.INSTANCE, project, text == null ? "" : text);
myShowAutocompletionIsAvailableHint = showAutocompletionIsAvailableHint;
+ myProvider = provider;
- if (provider != null) {
- TextFieldWithAutoCompletionContributor.installCompletion(getDocument(), project, provider, true);
- }
+ TextFieldWithAutoCompletionContributor.installCompletion(getDocument(), project, provider, true);
+ }
+
+ public static TextFieldWithAutoCompletion<String> create(final Project project,
+ @NotNull final Collection<String> items,
+ final boolean showAutocompletionIsAvailableHint,
+ @Nullable final String text) {
+ return create(project, items, null, showAutocompletionIsAvailableHint, text);
}
public static TextFieldWithAutoCompletion<String> create(final Project project,
@NotNull final Collection<String> items,
@Nullable final Icon icon,
- final boolean showAutocompletionIsAvailableHint, @Nullable final String text) {
+ final boolean showAutocompletionIsAvailableHint,
+ @Nullable final String text) {
return new TextFieldWithAutoCompletion<String>(project, new StringsCompletionProvider(items, icon), showAutocompletionIsAvailableHint,
text);
}
+ public void setVariants(@NotNull Collection<T> variants) {
+ myProvider.setItems(variants);
+ }
+
@Override
protected EditorEx createEditor() {
final EditorEx editor = super.createEditor();
@@ -83,8 +95,9 @@
return editor;
}
- final String completionShortcutText = getCompletionShortcutText();
- if (completionShortcutText == null) {
+ final String completionShortcutText =
+ KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_CODE_COMPLETION));
+ if (StringUtil.isEmpty(completionShortcutText)) {
return editor;
}
@@ -124,7 +137,7 @@
final ShortcutSet shortcutSet = action.getShortcutSet();
if (shortcutSet != null) {
final Shortcut[] shortcuts = shortcutSet.getShortcuts();
- if (shortcuts != null && shortcuts.length > 0) {
+ if (shortcuts.length > 0) {
return KeymapUtil.getShortcutText(shortcuts[0]);
}
}
diff --git a/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java b/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java
index 834779f..753dc09 100644
--- a/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java
+++ b/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java
@@ -43,16 +43,17 @@
public static <T> void installCompletion(Document document,
Project project,
- @Nullable TextFieldWithAutoCompletionListProvider<T> consumer,
+ @Nullable TextFieldWithAutoCompletionListProvider<T> provider,
boolean autoPopup) {
PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (psiFile != null) {
//noinspection unchecked
- psiFile.putUserData(KEY, consumer == null ? TextFieldWithAutoCompletion.EMPTY_COMPLETION : consumer);
+ psiFile.putUserData(KEY, provider == null ? TextFieldWithAutoCompletion.EMPTY_COMPLETION : provider);
psiFile.putUserData(AUTO_POPUP_KEY, autoPopup);
}
}
+
@Override
public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
PsiFile file = parameters.getOriginalFile();
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/AbstractIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/AbstractIndex.java
index 60949b8..10adf97 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/AbstractIndex.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/AbstractIndex.java
@@ -18,6 +18,7 @@
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author Eugene Zhuravlev
@@ -27,5 +28,5 @@
@NotNull
ValueContainer<Value> getData(Key key) throws StorageException;
- boolean processAllKeys(Processor<Key> processor) throws StorageException;
+ boolean processAllKeys(Processor<Key> processor, @Nullable IdFilter idFilter) throws StorageException;
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
index 642c455..c381c79 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
@@ -413,7 +413,8 @@
extension.getKeyDescriptor(),
extension.getValueExternalizer(),
extension.getCacheSize(),
- extension.isKeyHighlySelective()
+ extension.isKeyHighlySelective(),
+ extension.traceKeyHashToVirtualFileMapping()
);
final MemoryIndexStorage<K, V> memStorage = new MemoryIndexStorage<K, V>(storage);
@@ -722,13 +723,17 @@
@Override
public <K> boolean processAllKeys(@NotNull final ID<K, ?> indexId, Processor<K> processor, @Nullable Project project) {
+ return processAllKeys(indexId, processor, project != null ? GlobalSearchScope.allScope(project) : new EverythingGlobalScope(), null);
+ }
+
+ public <K> boolean processAllKeys(@NotNull ID<K, ?> indexId, Processor<K> processor, @NotNull GlobalSearchScope scope, @Nullable IdFilter idFilter) {
try {
final UpdatableIndex<K, ?, FileContent> index = getIndex(indexId);
if (index == null) {
return true;
}
- ensureUpToDate(indexId, project, project != null ? GlobalSearchScope.allScope(project) : new EverythingGlobalScope());
- return index.processAllKeys(processor);
+ ensureUpToDate(indexId, scope.getProject(), scope);
+ return index.processAllKeys(processor, idFilter);
}
catch (StorageException e) {
scheduleRebuild(indexId, e);
@@ -1014,7 +1019,7 @@
myContentlessIndicesUpdateQueue.signalUpdateEnd();
}
- public static final class ProjectIndexableFilesFilter {
+ public static final class ProjectIndexableFilesFilter extends IdFilter {
private static final int SHIFT = 6;
private static final int MASK = (1 << SHIFT) - 1;
private final long[] myBitMask;
@@ -1735,7 +1740,9 @@
}
FileType fileType = file.getFileType();
if(isProjectOrWorkspaceFile(file, fileType)) return Collections.emptyList();
-
+ if (fileType == StdFileTypes.HTML || fileType == StdFileTypes.XML) {
+ int a = 1;
+ }
List<ID<?, ?>> ids = myFileType2IndicesWithFileTypeInfoMap.get(fileType);
if (ids == null) ids = myIndicesWithoutFileTypeInfo;
return ids;
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexInfrastructure.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexInfrastructure.java
index 32abd28..900c6e3 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/IndexInfrastructure.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexInfrastructure.java
@@ -95,16 +95,14 @@
}
}
});
-
+ assert os != null;
try {
- if (os != null) {
- os.writeInt(version);
- os.writeInt(VERSION);
- }
+ os.writeInt(version);
+ os.writeInt(VERSION);
}
finally {
ourIndexIdToCreationStamp.clear();
- if (os != null) os.close();
+ os.close();
long max = Math.max(System.currentTimeMillis(), Math.max(prevLastModifiedValue, ourLastStamp) + 2000);
ourLastStamp = max;
file.setLastModified(max);
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java
index a268c0c..5e0296b 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexStorage.java
@@ -18,6 +18,7 @@
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.Flushable;
import java.io.IOException;
@@ -38,7 +39,7 @@
@NotNull
ValueContainer<Value> read(Key key) throws StorageException;
- boolean processKeys(Processor<Key> processor) throws StorageException;
+ boolean processKeys(Processor<Key> processor, @Nullable IdFilter idFilter) throws StorageException;
Collection<Key> getKeys() throws StorageException;
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java
index ffdc0ab..0448c65 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java
@@ -22,12 +22,13 @@
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import com.intellij.util.containers.SLRUCache;
-import com.intellij.util.io.DataExternalizer;
-import com.intellij.util.io.KeyDescriptor;
-import com.intellij.util.io.PersistentMap;
+import com.intellij.util.io.*;
+import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.DataInput;
+import java.io.DataOutput;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -42,7 +43,9 @@
*/
public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Value>{
private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.MapIndexStorage");
+ private final boolean myBuildKeyHashToVirtualFileMapping;
private PersistentMap<Key, ValueContainer<Value>> myMap;
+ private PersistentBTreeEnumerator<int[]> myKeyHashToVirtualFileMapping;
private SLRUCache<Key, ChangeTrackingValueContainer<Value>> myCache;
private final File myStorageFile;
private final KeyDescriptor<Key> myKeyDescriptor;
@@ -71,20 +74,23 @@
@NotNull DataExternalizer<Value> valueExternalizer,
final int cacheSize
) throws IOException {
- this(storageFile, keyDescriptor, valueExternalizer, cacheSize, false);
+ this(storageFile, keyDescriptor, valueExternalizer, cacheSize, false, false);
}
public MapIndexStorage(@NotNull File storageFile,
@NotNull KeyDescriptor<Key> keyDescriptor,
@NotNull DataExternalizer<Value> valueExternalizer,
final int cacheSize,
- boolean highKeySelectivity) throws IOException {
+ boolean highKeySelectivity,
+ boolean buildKeyHashToVirtualFileMapping
+ ) throws IOException {
myStorageFile = storageFile;
myKeyDescriptor = keyDescriptor;
myCacheSize = cacheSize;
myDataExternalizer = valueExternalizer;
myHighKeySelectivity = highKeySelectivity;
+ myBuildKeyHashToVirtualFileMapping = buildKeyHashToVirtualFileMapping && FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping;
initMapAndCache();
}
@@ -133,6 +139,37 @@
};
myMap = map;
+
+ myKeyHashToVirtualFileMapping = myBuildKeyHashToVirtualFileMapping ? new PersistentBTreeEnumerator<int[]>(getProjectFile(), new KeyDescriptor<int[]>() {
+ @Override
+ public void save(DataOutput out, int[] value) throws IOException {
+ DataInputOutputUtil.writeINT(out, value[0]);
+ DataInputOutputUtil.writeINT(out, value[1]);
+ }
+
+ @Override
+ public int[] read(DataInput in) throws IOException {
+ return new int[] {DataInputOutputUtil.readINT(in), DataInputOutputUtil.readINT(in)};
+ }
+
+ @Override
+ public int getHashCode(int[] value) {
+ return value[0] * 31 + value[1];
+ }
+
+ @Override
+ public boolean isEqual(int[] val1, int[] val2) {
+ return val1[0] == val2[0] && val1[1] == val2[1];
+ }
+ }, 4096) {
+ protected boolean serializationEquivalenceIsExhausting() {
+ return true;
+ }
+ }: null;
+ }
+
+ private File getProjectFile() {
+ return new File(myStorageFile.getPath() + ".project");
}
@Override
@@ -143,6 +180,7 @@
myCache.clear();
myMap.force();
}
+ if (myKeyHashToVirtualFileMapping != null) myKeyHashToVirtualFileMapping.force();
}
finally {
l.unlock();
@@ -154,6 +192,7 @@
try {
myLowMemoryFlusher.stop();
flush();
+ if (myKeyHashToVirtualFileMapping != null) myKeyHashToVirtualFileMapping.close();
myMap.close();
}
catch (IOException e) {
@@ -175,12 +214,14 @@
public void clear() throws StorageException{
try {
myMap.close();
+ if (myKeyHashToVirtualFileMapping != null) myKeyHashToVirtualFileMapping.close();
}
catch (IOException e) {
LOG.error(e);
}
try {
FileUtil.delete(myStorageFile);
+ if (myKeyHashToVirtualFileMapping != null) IOUtil.deleteAllFilesStartingWith(getProjectFile());
initMapAndCache();
}
catch (IOException e) {
@@ -199,10 +240,32 @@
}
@Override
- public boolean processKeys(final Processor<Key> processor) throws StorageException {
+ public boolean processKeys(final Processor<Key> processor, final IdFilter idFilter) throws StorageException {
l.lock();
try {
myCache.clear(); // this will ensure that all new keys are made into the map
+ if (myBuildKeyHashToVirtualFileMapping && idFilter != null) {
+ final TIntHashSet hashMaskSet = new TIntHashSet(1000);
+ long l = System.currentTimeMillis();
+ myKeyHashToVirtualFileMapping.iterateData(new Processor<int[]>() {
+ @Override
+ public boolean process(int[] key) {
+ if (!idFilter.contains(key[1])) return true;
+ hashMaskSet.add(key[0]);
+ return true;
+ }
+ });
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Scanned keyHashToVirtualFileMapping of " + myStorageFile + " for " + (System.currentTimeMillis() - l));
+ }
+ return myMap.processKeys(new Processor<Key>() {
+ @Override
+ public boolean process(Key key) {
+ if (!hashMaskSet.contains(myKeyDescriptor.getHashCode(key))) return true;
+ return processor.process(key);
+ }
+ });
+ }
return myMap.processKeys(processor);
}
catch (IOException e) {
@@ -227,7 +290,7 @@
@Override
public Collection<Key> getKeys() throws StorageException {
List<Key> keys = new ArrayList<Key>();
- processKeys(new CommonProcessors.CollectProcessor<Key>(keys));
+ processKeys(new CommonProcessors.CollectProcessor<Key>(keys), null);
return keys;
}
@@ -256,6 +319,10 @@
@Override
public void addValue(final Key key, final int inputId, final Value value) throws StorageException {
try {
+ if (myKeyHashToVirtualFileMapping != null) {
+ myKeyHashToVirtualFileMapping.enumerate(new int[] { myKeyDescriptor.getHashCode(key), inputId });
+ }
+
myMap.markDirty();
if (!myHighKeySelectivity) {
read(key).addValue(inputId, value);
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java
index e93ca8b..98b62a5 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java
@@ -155,11 +155,11 @@
}
@Override
- public boolean processAllKeys(Processor<Key> processor) throws StorageException {
+ public boolean processAllKeys(Processor<Key> processor, IdFilter idFilter) throws StorageException {
final Lock lock = getReadLock();
try {
lock.lock();
- return myStorage.processKeys(processor);
+ return myStorage.processKeys(processor, idFilter);
}
finally {
lock.unlock();
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java
index 7a87af7..f07fc85 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java
@@ -101,12 +101,12 @@
@Override
public Collection<Key> getKeys() throws StorageException {
final Set<Key> keys = new HashSet<Key>();
- processKeys(new CommonProcessors.CollectProcessor<Key>(keys));
+ processKeys(new CommonProcessors.CollectProcessor<Key>(keys), null);
return keys;
}
@Override
- public boolean processKeys(final Processor<Key> processor) throws StorageException {
+ public boolean processKeys(final Processor<Key> processor, IdFilter idFilter) throws StorageException {
final Set<Key> stopList = new HashSet<Key>();
Processor<Key> decoratingProcessor = new Processor<Key>() {
@@ -128,7 +128,7 @@
}
stopList.add(key);
}
- return myBackendStorage.processKeys(decoratingProcessor);
+ return myBackendStorage.processKeys(stopList.size() == 0 && myMap.size() == 0 ? processor : decoratingProcessor, idFilter);
}
@Override
diff --git a/platform/lang-impl/testSources/com/intellij/execution/impl/ModuleRunConfigurationManagerTest.java b/platform/lang-impl/testSources/com/intellij/execution/impl/ModuleRunConfigurationManagerTest.java
index d5906e5..943cbbf 100644
--- a/platform/lang-impl/testSources/com/intellij/execution/impl/ModuleRunConfigurationManagerTest.java
+++ b/platform/lang-impl/testSources/com/intellij/execution/impl/ModuleRunConfigurationManagerTest.java
@@ -68,6 +68,7 @@
createSettings("other-module-run", new MyModuleBasedConfiguration("other-module-run-config", getProject(), getModule())),
mySettings
);
+ myManager.myManager.myExternalSettings.put(myManager.myRemoverKey, Collections.singletonList(mySettings));
myConfigurations = Collections.unmodifiableCollection(configs);
}
@@ -107,13 +108,13 @@
public void testBeforeOtherModuleRemoved() throws Exception {
myRemovedSettings.clear();
- myManager.beforeModuleRemoved(getProject(), getModule());
+ myManager.moduleRemoved(getProject(), getModule());
assertEmpty("No settings should be removed", myRemovedSettings);
}
public void testBeforeMyModuleRemoved() throws Exception {
myRemovedSettings.clear();
- myManager.beforeModuleRemoved(getProject(), myModule);
+ myManager.moduleRemoved(getProject(), myModule);
assertSameElements("one run config should be removed", myRemovedSettings, Collections.singleton(mySettings));
}
diff --git a/platform/platform-api/src/com/intellij/ide/XmlRpcServer.java b/platform/platform-api/src/com/intellij/ide/XmlRpcServer.java
index 24e06e6..16dafdc 100644
--- a/platform/platform-api/src/com/intellij/ide/XmlRpcServer.java
+++ b/platform/platform-api/src/com/intellij/ide/XmlRpcServer.java
@@ -16,8 +16,8 @@
package com.intellij.ide;
import com.intellij.openapi.components.ServiceManager;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.handler.codec.http.HttpRequest;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.http.FullHttpRequest;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,7 +31,7 @@
void removeHandler(String name);
- boolean process(@NotNull String path, @NotNull HttpRequest request, @NotNull ChannelHandlerContext context, @Nullable Map<String, Object> handlers) throws IOException;
+ boolean process(@NotNull String path, @NotNull FullHttpRequest request, @NotNull ChannelHandlerContext context, @Nullable Map<String, Object> handlers) throws IOException;
final class SERVICE {
private SERVICE() {
diff --git a/platform/platform-api/src/com/intellij/openapi/application/ApplicationAdapter.java b/platform/platform-api/src/com/intellij/openapi/application/ApplicationAdapter.java
index 00f38c9..ddeaa8c 100644
--- a/platform/platform-api/src/com/intellij/openapi/application/ApplicationAdapter.java
+++ b/platform/platform-api/src/com/intellij/openapi/application/ApplicationAdapter.java
@@ -15,22 +15,25 @@
*/
package com.intellij.openapi.application;
-import com.intellij.openapi.wm.IdeFrame;
-
public abstract class ApplicationAdapter implements ApplicationListener {
+ @Override
public boolean canExitApplication() {
return true;
}
+ @Override
public void applicationExiting() {
}
+ @Override
public void beforeWriteActionStart(Object action) {
}
+ @Override
public void writeActionStarted(Object action) {
}
+ @Override
public void writeActionFinished(Object action) {
}
}
\ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/wm/StatusBarWidget.java b/platform/platform-api/src/com/intellij/openapi/wm/StatusBarWidget.java
index 8382553..2e77707 100644
--- a/platform/platform-api/src/com/intellij/openapi/wm/StatusBarWidget.java
+++ b/platform/platform-api/src/com/intellij/openapi/wm/StatusBarWidget.java
@@ -130,7 +130,7 @@
}
public Insets getBorderInsets(Component c) {
- return new Insets(2, 4, 2, 2);
+ return new Insets(0, 4, 0, 2);
}
public boolean isBorderOpaque() {
diff --git a/platform/platform-api/src/com/intellij/ui/ExpandableItemsHandler.java b/platform/platform-api/src/com/intellij/ui/ExpandableItemsHandler.java
index 4904b16..b9146bc 100644
--- a/platform/platform-api/src/com/intellij/ui/ExpandableItemsHandler.java
+++ b/platform/platform-api/src/com/intellij/ui/ExpandableItemsHandler.java
@@ -21,6 +21,8 @@
public interface ExpandableItemsHandler<T> {
void setEnabled(boolean enabled);
+
+ boolean isEnabled();
@NotNull
Collection<T> getExpandedItems();
diff --git a/platform/platform-api/src/com/intellij/ui/ExpandableItemsHandlerFactory.java b/platform/platform-api/src/com/intellij/ui/ExpandableItemsHandlerFactory.java
index b9002b9..e6e2039 100644
--- a/platform/platform-api/src/com/intellij/ui/ExpandableItemsHandlerFactory.java
+++ b/platform/platform-api/src/com/intellij/ui/ExpandableItemsHandlerFactory.java
@@ -58,6 +58,11 @@
public void setEnabled(boolean enabled) {
}
+ @Override
+ public boolean isEnabled() {
+ return false;
+ }
+
@NotNull
@Override
public Collection<Object> getExpandedItems() {
diff --git a/platform/platform-api/src/com/intellij/ui/ScreenUtil.java b/platform/platform-api/src/com/intellij/ui/ScreenUtil.java
index 00300b3..8f46df3 100644
--- a/platform/platform-api/src/com/intellij/ui/ScreenUtil.java
+++ b/platform/platform-api/src/com/intellij/ui/ScreenUtil.java
@@ -15,7 +15,6 @@
*/
package com.intellij.ui;
-import com.intellij.Patches;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.containers.WeakHashMap;
@@ -165,10 +164,6 @@
}
private static Insets calcInsets(GraphicsConfiguration gc) {
- if (Patches.SUN_BUG_ID_9000030 && GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices().length > 1) {
- return new Insets(0, 0, 0, 0);
- }
-
return Toolkit.getDefaultToolkit().getScreenInsets(gc);
}
diff --git a/platform/platform-api/src/com/intellij/util/Alarm.java b/platform/platform-api/src/com/intellij/util/Alarm.java
index 6b9a48d..56bab6e 100644
--- a/platform/platform-api/src/com/intellij/util/Alarm.java
+++ b/platform/platform-api/src/com/intellij/util/Alarm.java
@@ -253,9 +253,19 @@
private Future<?> myFuture; // guarded by LOCK
private final long myDelay;
- private Request(@NotNull Runnable task, @Nullable ModalityState modalityState, long delayMillis) {
+ private Request(@NotNull final Runnable task, @Nullable ModalityState modalityState, long delayMillis) {
synchronized (LOCK) {
- myTask = task;
+ myTask = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ task.run();
+ }
+ catch (Exception e) {
+ LOG.error("Exception in task " + task, e);
+ }
+ }
+ };
myModalityState = modalityState;
myDelay = delayMillis;
}
@@ -284,16 +294,12 @@
myFuture = null;
}
- try {
- if (myThreadToUse == ThreadToUse.SWING_THREAD && !isEdt()) {
- SwingUtilities.invokeAndWait(task);
- }
- else {
- task.run();
- }
+ if (myThreadToUse == ThreadToUse.SWING_THREAD && !isEdt()) {
+ //noinspection SSBasedInspection
+ SwingUtilities.invokeLater(task);
}
- catch (Exception e) {
- LOG.error("Exception in task " + task, e);
+ else {
+ task.run();
}
}
};
@@ -307,6 +313,7 @@
else {
final Application app = ApplicationManager.getApplication();
if (app == null) {
+ //noinspection SSBasedInspection
SwingUtilities.invokeLater(scheduledTask);
}
else {
diff --git a/platform/platform-api/src/com/intellij/util/PlatformUtils.java b/platform/platform-api/src/com/intellij/util/PlatformUtils.java
index b768cb4..ddc25df 100644
--- a/platform/platform-api/src/com/intellij/util/PlatformUtils.java
+++ b/platform/platform-api/src/com/intellij/util/PlatformUtils.java
@@ -56,6 +56,10 @@
return RUBY_PREFIX.equals(getPlatformPrefix());
}
+ public static boolean isCidr() {
+ return isAppCode() || isCppIde();
+ }
+
public static boolean isAppCode() {
return APPCODE_PREFIX.equals(getPlatformPrefix());
}
diff --git a/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java b/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java
index aeccece..5368582 100644
--- a/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java
+++ b/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java
@@ -15,18 +15,18 @@
*/
package org.jetbrains.ide;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.handler.codec.http.HttpMethod;
-import org.jboss.netty.handler.codec.http.HttpRequest;
-import org.jboss.netty.handler.codec.http.QueryStringDecoder;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.http.FullHttpRequest;
+import io.netty.handler.codec.http.HttpMethod;
+import io.netty.handler.codec.http.QueryStringDecoder;
import java.io.IOException;
public abstract class HttpRequestHandler {
- public boolean isSupported(HttpRequest request) {
+ public boolean isSupported(FullHttpRequest request) {
return request.getMethod() == HttpMethod.GET || request.getMethod() == HttpMethod.HEAD;
}
- public abstract boolean process(QueryStringDecoder urlDecoder, HttpRequest request, ChannelHandlerContext context)
+ public abstract boolean process(QueryStringDecoder urlDecoder, FullHttpRequest request, ChannelHandlerContext context)
throws IOException;
}
diff --git a/platform/platform-impl/src/com/intellij/help/impl/MacHelpUtil.java b/platform/platform-impl/src/com/intellij/help/impl/MacHelpUtil.java
index cfbe60e..2728c45 100644
--- a/platform/platform-impl/src/com/intellij/help/impl/MacHelpUtil.java
+++ b/platform/platform-impl/src/com/intellij/help/impl/MacHelpUtil.java
@@ -41,6 +41,6 @@
}
static boolean isApplicable() {
- return SystemInfo.isMac && Registry.is("ide.mac.show.native.help", false) && !PlatformUtils.isAppCode() && !PlatformUtils.isCommunity();
+ return SystemInfo.isMac && Registry.is("ide.mac.show.native.help", false) && !PlatformUtils.isCidr() && !PlatformUtils.isCommunity();
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java
index f1c75e0..db1e782 100644
--- a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java
@@ -20,15 +20,14 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import gnu.trove.THashMap;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufInputStream;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.http.FullHttpRequest;
+import io.netty.handler.codec.http.HttpMethod;
+import io.netty.handler.codec.http.QueryStringDecoder;
import org.apache.xmlrpc.*;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBufferInputStream;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.handler.codec.http.HttpMethod;
-import org.jboss.netty.handler.codec.http.HttpRequest;
-import org.jboss.netty.handler.codec.http.HttpResponse;
-import org.jboss.netty.handler.codec.http.QueryStringDecoder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.ide.HttpRequestHandler;
@@ -57,13 +56,13 @@
static final class XmlRpcRequestHandler extends HttpRequestHandler {
@Override
- public boolean isSupported(HttpRequest request) {
+ public boolean isSupported(FullHttpRequest request) {
return request.getMethod() == HttpMethod.POST || request.getMethod() == HttpMethod.OPTIONS;
}
@Override
- public boolean process(QueryStringDecoder urlDecoder, HttpRequest request, ChannelHandlerContext context) throws IOException {
- return SERVICE.getInstance().process(urlDecoder.getPath(), request, context, null);
+ public boolean process(QueryStringDecoder urlDecoder, FullHttpRequest request, ChannelHandlerContext context) throws IOException {
+ return SERVICE.getInstance().process(urlDecoder.path(), request, context, null);
}
}
@@ -83,14 +82,14 @@
}
@Override
- public boolean process(@NotNull String path, @NotNull HttpRequest request, @NotNull ChannelHandlerContext context, @Nullable Map<String, Object> handlers) throws IOException {
+ public boolean process(@NotNull String path, @NotNull FullHttpRequest request, @NotNull ChannelHandlerContext context, @Nullable Map<String, Object> handlers) throws IOException {
if (!(path.isEmpty() || (path.length() == 1 && path.charAt(0) == '/') || path.equalsIgnoreCase("/RPC2"))) {
return false;
}
if (request.getMethod() == HttpMethod.POST) {
- ChannelBuffer result;
- ChannelBufferInputStream in = new ChannelBufferInputStream(request.getContent());
+ ByteBuf result;
+ ByteBufInputStream in = new ByteBufInputStream(request.content());
try {
XmlRpcServerRequest xmlRpcServerRequest = new XmlRpcRequestProcessor().decodeRequest(in);
@@ -100,10 +99,10 @@
}
Object response = invokeHandler(getHandler(xmlRpcServerRequest.getMethodName(), handlers == null ? handlerMapping : handlers), xmlRpcServerRequest);
- result = ChannelBuffers.copiedBuffer(new XmlRpcResponseProcessor().encodeResponse(response, CharsetToolkit.UTF8));
+ result = Unpooled.copiedBuffer(new XmlRpcResponseProcessor().encodeResponse(response, CharsetToolkit.UTF8));
}
catch (Throwable e) {
- context.getChannel().close();
+ context.channel().close();
LOG.error(e);
return true;
}
@@ -111,12 +110,10 @@
in.close();
}
- HttpResponse response = Responses.create("text/xml");
- response.setContent(result);
- Responses.send(response, context.getChannel(), request);
+ Responses.send(Responses.response("text/xml", result), context.channel(), request);
return true;
}
- else if (HttpMethod.POST.getName().equals(request.getHeader("Access-Control-Request-Method"))) {
+ else if (HttpMethod.POST.name().equals(request.headers().get("Access-Control-Request-Method"))) {
LOG.assertTrue(request.getMethod() == HttpMethod.OPTIONS);
Responses.sendOptionsResponse("POST, OPTIONS", request, context);
return true;
diff --git a/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java
index 4f3954c7..e475b5b 100644
--- a/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java
@@ -78,7 +78,9 @@
@Nullable
private Object getDataFromProvider(@NotNull final DataProvider provider, @NotNull String dataId, @Nullable Set<String> alreadyComputedIds) {
- if (alreadyComputedIds != null && alreadyComputedIds.contains(dataId)) return null;
+ if (alreadyComputedIds != null && alreadyComputedIds.contains(dataId)) {
+ return null;
+ }
try {
Object data = provider.getData(dataId);
if (data != null) return validated(data, dataId, provider);
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/customization/ActionUrl.java b/platform/platform-impl/src/com/intellij/ide/ui/customization/ActionUrl.java
index 05f3e2d..aa9ea80 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/customization/ActionUrl.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/customization/ActionUrl.java
@@ -276,4 +276,15 @@
public void setGroupPath(final ArrayList<String> groupPath) {
myGroupPath = groupPath;
}
+
+ @Override
+ public String toString() {
+ return "ActionUrl{" +
+ "myGroupPath=" + myGroupPath +
+ ", myComponent=" + myComponent +
+ ", myActionType=" + myActionType +
+ ", myAbsolutePosition=" + myAbsolutePosition +
+ ", myInitialPosition=" + myInitialPosition +
+ '}';
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/customization/CustomActionsSchema.java b/platform/platform-impl/src/com/intellij/ide/ui/customization/CustomActionsSchema.java
index 04942ab..9359d31 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/customization/CustomActionsSchema.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/customization/CustomActionsSchema.java
@@ -21,6 +21,7 @@
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.IdeActions;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.ExportableComponent;
import com.intellij.openapi.components.ServiceManager;
@@ -135,6 +136,10 @@
public boolean isModified(CustomActionsSchema schema) {
final ArrayList<ActionUrl> storedActions = schema.getActions();
+ if (ApplicationManager.getApplication().isUnitTestMode() && !storedActions.isEmpty()) {
+ System.err.println("stored: " + storedActions.toString());
+ System.err.println("actual: " + getActions().toString());
+ }
if (storedActions.size() != getActions().size()) {
return true;
}
@@ -170,6 +175,9 @@
url.readExternal((Element)groupElement);
myActions.add(url);
}
+ if (ApplicationManager.getApplication().isUnitTestMode()) {
+ System.err.println("read custom actions: " + myActions.toString());
+ }
readIcons(element);
}
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties
index 5922749..bda380c 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties
@@ -102,6 +102,8 @@
SplitPane.highlight=3c3f41
+TreeUI=com.intellij.ide.ui.laf.darcula.ui.DarculaTreeUI
+
Hyperlink.linkColor=589df6
#List.background=45494A
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTreeUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTreeUI.java
new file mode 100644
index 0000000..b9190ea
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTreeUI.java
@@ -0,0 +1,31 @@
+/*
+ * 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.ui.laf.darcula.ui;
+
+import com.intellij.util.ui.tree.WideSelectionTreeUI;
+
+import javax.swing.*;
+import javax.swing.plaf.ComponentUI;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class DarculaTreeUI extends WideSelectionTreeUI {
+ @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
+ public static ComponentUI createUI(JComponent c) {
+ return new DarculaTreeUI();
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
index 8d9768e..ffaee05 100644
--- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
+++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
@@ -105,6 +105,7 @@
loadSystemLibraries(log);
if (!Main.isHeadless()) {
+ AppUIUtil.patchSystem();
AppUIUtil.updateWindowIcon(JOptionPane.getRootFrame());
AppUIUtil.registerBundledFonts();
}
@@ -275,7 +276,7 @@
DateFormatUtilRt.formatBuildDate(appInfo.getBuildDate()) + ")");
log.info("OS: " + SystemInfoRt.OS_NAME + " (" + SystemInfoRt.OS_VERSION + ")");
log.info("JRE: " + System.getProperty("java.runtime.version", "-") + " (" + System.getProperty("java.vendor", "-") + ")");
- log.info("JVM: " + System.getProperty("java.vm.version", "-") + " (" + System.getProperty("java.vm.vendor", "-") + ")");
+ log.info("JVM: " + System.getProperty("java.vm.version", "-") + " (" + System.getProperty("java.vm.name", "-") + ")");
List<String> arguments = ManagementFactory.getRuntimeMXBean().getInputArguments();
if (arguments != null) {
diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/OsInfoUsageCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/OsInfoUsageCollector.java
new file mode 100644
index 0000000..949cc36
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/internal/statistic/OsInfoUsageCollector.java
@@ -0,0 +1,44 @@
+/*
+ * 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.internal.statistic;
+
+import com.intellij.internal.statistic.beans.GroupDescriptor;
+import com.intellij.internal.statistic.beans.UsageDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Set;
+
+/**
+ * @author peter
+ */
+public class OsInfoUsageCollector extends UsagesCollector {
+ @NotNull
+ @Override
+ public Set<UsageDescriptor> getUsages(@Nullable Project project) throws CollectUsagesException {
+ return ContainerUtil.newHashSet(new UsageDescriptor(SystemInfo.OS_NAME, 1),
+ new UsageDescriptor(SystemInfo.OS_NAME + " " + SystemInfo.OS_VERSION, 1));
+ }
+
+ @NotNull
+ @Override
+ public GroupDescriptor getGroupId() {
+ return GroupDescriptor.create("user.os");
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java b/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java
index 272f80f..f4c792a 100644
--- a/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java
+++ b/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java
@@ -19,6 +19,7 @@
import com.intellij.execution.impl.ConsoleViewUtil;
import com.intellij.execution.impl.EditorHyperlinkSupport;
import com.intellij.execution.ui.ConsoleViewContentType;
+import com.intellij.icons.AllIcons;
import com.intellij.notification.impl.NotificationsManagerImpl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
@@ -88,7 +89,7 @@
((EditorMarkupModel)editor.getMarkupModel()).setErrorStripeVisible(true);
- final ClearLog clearLog = new ClearLog();
+ final ClearLogAction clearLog = new ClearLogAction(this);
clearLog.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.CONSOLE_CLEAR_ALL).getShortcutSet(), editor.getContentComponent());
editor.addEditorMouseListener(new EditorPopupHandler() {
@@ -102,7 +103,7 @@
return editor;
}
- private DefaultActionGroup createPopupActions(ActionManager actionManager, ClearLog action) {
+ private DefaultActionGroup createPopupActions(ActionManager actionManager, ClearLogAction action) {
AnAction[] children = ((ActionGroup)actionManager.getAction(IdeActions.GROUP_CONSOLE_EDITOR_POPUP)).getChildren(null);
DefaultActionGroup group = new DefaultActionGroup(children);
group.addSeparator();
@@ -223,24 +224,27 @@
document.insertString(document.getTextLength(), s);
}
- private class ClearLog extends DumbAwareAction {
- public ClearLog() {
- super("Clear All");
+ public static class ClearLogAction extends DumbAwareAction {
+ private EventLogConsole myConsole;
+
+ public ClearLogAction(EventLogConsole console) {
+ super("Clear All", "Clear the contents of the Event Log", AllIcons.Actions.GC);
+ myConsole = console;
}
@Override
public void update(AnActionEvent e) {
- final boolean enabled = e.getData(PlatformDataKeys.EDITOR) != null;
- e.getPresentation().setEnabled(enabled);
- e.getPresentation().setVisible(enabled);
+ Editor editor = e.getData(PlatformDataKeys.EDITOR);
+ e.getPresentation().setEnabled(editor != null && editor.getDocument().getTextLength() > 0);
}
public void actionPerformed(final AnActionEvent e) {
- for (Notification notification : myProjectModel.getNotifications()) {
+ LogModel model = myConsole.myProjectModel;
+ for (Notification notification : model.getNotifications()) {
notification.expire();
- myProjectModel.removeNotification(notification);
+ model.removeNotification(notification);
}
- myProjectModel.setStatusMessage(null, 0);
+ model.setStatusMessage(null, 0);
final Editor editor = e.getData(PlatformDataKeys.EDITOR);
if (editor != null) {
editor.getDocument().deleteString(0, editor.getDocument().getTextLength());
diff --git a/platform/platform-impl/src/com/intellij/notification/EventLogToolWindowFactory.java b/platform/platform-impl/src/com/intellij/notification/EventLogToolWindowFactory.java
index 6db8dc7..b25c470 100644
--- a/platform/platform-impl/src/com/intellij/notification/EventLogToolWindowFactory.java
+++ b/platform/platform-impl/src/com/intellij/notification/EventLogToolWindowFactory.java
@@ -15,6 +15,8 @@
*/
package com.intellij.notification;
+import com.intellij.execution.ExecutionBundle;
+import com.intellij.execution.ui.ConsoleView;
import com.intellij.icons.AllIcons;
import com.intellij.ide.actions.ContextHelpAction;
import com.intellij.notification.impl.NotificationsConfigurable;
@@ -44,7 +46,8 @@
public class EventLogToolWindowFactory implements ToolWindowFactory, DumbAware {
@Override
public void createToolWindowContent(final Project project, ToolWindow toolWindow) {
- final Editor editor = EventLog.getProjectComponent(project).getConsole().getConsoleEditor();
+ EventLogConsole console = EventLog.getProjectComponent(project).getConsole();
+ final Editor editor = console.getConsoleEditor();
SimpleToolWindowPanel panel = new SimpleToolWindowPanel(false, true) {
@Override
@@ -55,21 +58,22 @@
panel.setContent(editor.getComponent());
panel.addAncestorListener(new LogShownTracker(project));
- ActionToolbar toolbar = createToolbar(project, editor);
- toolbar.setTargetComponent(panel);
+ ActionToolbar toolbar = createToolbar(project, editor, console);
+ toolbar.setTargetComponent(editor.getContentComponent());
panel.setToolbar(toolbar.getComponent());
final Content content = ContentFactory.SERVICE.getInstance().createContent(panel, "", false);
toolWindow.getContentManager().addContent(content);
}
- private static ActionToolbar createToolbar(Project project, Editor editor) {
+ private static ActionToolbar createToolbar(Project project, Editor editor, EventLogConsole console) {
DefaultActionGroup group = new DefaultActionGroup();
group.add(new EditNotificationSettings(project));
group.add(new DisplayBalloons());
group.add(new ToggleSoftWraps(editor));
group.add(new ScrollToTheEndToolbarAction(editor));
group.add(new MarkAllAsRead(project));
+ group.add(new EventLogConsole.ClearLogAction(console));
group.add(new ContextHelpAction(EventLog.HELP_ID));
return ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, false);
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/TextDiffType.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/TextDiffType.java
index 29f4f97..6db2d74 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/TextDiffType.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/TextDiffType.java
@@ -120,7 +120,7 @@
}
@Nullable
- public TextAttributes getTextAttributes(EditorColorsScheme scheme) {
+ public TextAttributes getTextAttributes(@NotNull EditorColorsScheme scheme) {
return scheme.getAttributes(myAttributesKey);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollToTheEndToolbarAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollToTheEndToolbarAction.java
index 2c47932..5ddbceed 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollToTheEndToolbarAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollToTheEndToolbarAction.java
@@ -19,14 +19,16 @@
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.util.EditorUtil;
+import com.intellij.openapi.project.DumbAwareAction;
import org.jetbrains.annotations.NotNull;
/**
* @author oleg
*/
-public class ScrollToTheEndToolbarAction extends AnAction {
+public class ScrollToTheEndToolbarAction extends DumbAwareAction {
private final Editor myEditor;
public ScrollToTheEndToolbarAction(@NotNull final Editor editor) {
@@ -39,6 +41,14 @@
}
@Override
+ public void update(AnActionEvent e) {
+ Document document = myEditor.getDocument();
+ int caretOffset = myEditor.getCaretModel().getOffset();
+ boolean isOnLastLine = document.getLineNumber(caretOffset) == document.getLineCount() - 1;
+ e.getPresentation().setEnabled(!isOnLastLine);
+ }
+
+ @Override
public void actionPerformed(AnActionEvent e) {
EditorUtil.scrollToTheEnd(myEditor);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java
index 795c65c..efc40e2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java
@@ -117,6 +117,7 @@
PrevNextActionsDescriptor descriptor = new PrevNextActionsDescriptor(IdeActions.ACTION_NEXT_EDITOR_TAB, IdeActions.ACTION_PREVIOUS_EDITOR_TAB);
final TabbedPaneWrapper.AsJBTabs wrapper = new TabbedPaneWrapper.AsJBTabs(fileEditorManager.getProject(), SwingConstants.BOTTOM, descriptor, this);
wrapper.getTabs().getPresentation().setPaintBorder(0, 0, 0, 0).setTabSidePaintBorder(1).setGhostsAlwaysVisible(true).setUiDecorator(new UiDecorator() {
+ @Override
@NotNull
public UiDecoration getDecoration() {
return new UiDecoration(null, new Insets(0, 8, 0, 8));
@@ -126,14 +127,17 @@
myTabbedPaneWrapper=wrapper;
myComponent=new MyComponent(wrapper.getComponent()){
+ @Override
public boolean requestFocusInWindow() {
return wrapper.getComponent().requestFocusInWindow();
}
+ @Override
public void requestFocus() {
wrapper.getComponent().requestFocus();
}
+ @Override
public boolean requestDefaultFocus() {
return wrapper.getComponent().requestDefaultFocus();
}
@@ -146,6 +150,7 @@
else if(editors.length==1){
myTabbedPaneWrapper=null;
myComponent = new MyComponent(createEditorComponent(editors[0])){
+ @Override
public void requestFocus() {
JComponent component = editors[0].getPreferredFocusedComponent();
if (component != null) {
@@ -153,6 +158,7 @@
}
}
+ @Override
public boolean requestFocusInWindow() {
JComponent component = editors[0].getPreferredFocusedComponent();
if (component != null) {
@@ -162,6 +168,7 @@
return false;
}
+ @Override
public boolean requestDefaultFocus() {
JComponent component = editors[0].getPreferredFocusedComponent();
if (component != null) {
@@ -383,6 +390,7 @@
* Handles changes of selected myEditor
*/
private final class MyChangeListener implements ChangeListener{
+ @Override
public void stateChanged(ChangeEvent e) {
FileEditor oldSelectedEditor = mySelectedEditor;
LOG.assertTrue(oldSelectedEditor != null);
@@ -399,6 +407,7 @@
add(realComponent, BorderLayout.CENTER);
}
+ @Override
public final Object getData(String dataId){
if (PlatformDataKeys.FILE_EDITOR.is(dataId)) {
return getSelectedEditor();
@@ -421,6 +430,7 @@
}
}
+ @Override
public void dispose() {
for (FileEditor editor : myEditors) {
if (!Disposer.isDisposed(editor)) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java
index a93a0bb..a608003 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java
@@ -60,6 +60,7 @@
uiSettings.addUISettingsListener(new MyUISettingsListener(), project);
}
+ @Override
public void projectOpened(){
MessageBusConnection connection = myProject.getMessageBus().connect();
@@ -68,6 +69,7 @@
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(
new DumbAwareRunnable() {
+ @Override
public void run() {
// myElement may be null if node that corresponds to this manager does not exist
if (myElement != null) {
@@ -95,6 +97,7 @@
);
}
+ @Override
@NotNull
public String getComponentName(){
return "editorHistoryManager";
@@ -305,6 +308,7 @@
}
}
+ @Override
public void readExternal(final Element element) {
// we have to delay xml processing because history entries require EditorStates to be created
// which is done via corresponding EditorProviders, those are not accessible before their
@@ -312,6 +316,7 @@
myElement = element.clone();
}
+ @Override
public void writeExternal(final Element element){
// update history before saving
final VirtualFile[] openFiles = FileEditorManager.getInstance(myProject).getOpenFiles();
@@ -331,10 +336,12 @@
* Updates history
*/
private final class MyEditorManagerListener extends FileEditorManagerAdapter{
+ @Override
public void fileOpened(@NotNull final FileEditorManager source, @NotNull final VirtualFile file){
fileOpenedImpl(file);
}
+ @Override
public void selectionChanged(@NotNull final FileEditorManagerEvent event){
updateHistoryEntry(event.getOldFile(), event.getOldEditor(), event.getOldProvider(), false);
updateHistoryEntry(event.getNewFile(), true);
@@ -352,6 +359,7 @@
* Cuts/extends history length
*/
private final class MyUISettingsListener implements UISettingsListener{
+ @Override
public void uiSettingsChanged(final UISettings source) {
trimToSize();
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java
index 2db0bbd..51ebe7d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java
@@ -86,11 +86,13 @@
final ActionManager actionManager = ActionManager.getInstance();
myTabs = new JBEditorTabs(project, actionManager, IdeFocusManager.getInstance(project), this);
myTabs.setDataProvider(new MyDataProvider()).setPopupGroup(new Getter<ActionGroup>() {
+ @Override
public ActionGroup get() {
return (ActionGroup)CustomActionsSchema.getInstance().getCorrectedAction(IdeActions.GROUP_EDITOR_TAB_POPUP);
}
}, ActionPlaces.EDITOR_TAB_POPUP, false).setNavigationActionsEnabled(false).addTabMouseListener(new TabMouseListener()).getPresentation()
.setTabDraggingEnabled(true).setUiDecorator(new UiDecorator() {
+ @Override
@NotNull
public UiDecoration getDecoration() {
return new UiDecoration(null, new Insets(TabsUtil.TAB_VERTICAL_PADDING, 10, TabsUtil.TAB_VERTICAL_PADDING, 10));
@@ -98,6 +100,7 @@
}).setTabLabelActionsMouseDeadzone(TimedDeadzone.NULL).setGhostsAlwaysVisible(true).setTabLabelActionsAutoHide(false)
.setActiveTabFillIn(EditorColorsManager.getInstance().getGlobalScheme().getDefaultBackground()).setPaintFocus(false).getJBTabs()
.addListener(new TabsListener.Adapter() {
+ @Override
public void selectionChanged(final TabInfo oldSelection, final TabInfo newSelection) {
final FileEditorManager editorManager = FileEditorManager.getInstance(myProject);
final FileEditor oldEditor = oldSelection != null ? editorManager.getSelectedEditor((VirtualFile)oldSelection.getObject()) : null;
@@ -142,16 +145,19 @@
updateTabBorder();
((ToolWindowManagerEx)ToolWindowManager.getInstance(myProject)).addToolWindowManagerListener(new ToolWindowManagerAdapter() {
+ @Override
public void stateChanged() {
updateTabBorder();
}
+ @Override
public void toolWindowRegistered(@NotNull final String id) {
updateTabBorder();
}
});
UISettings.getInstance().addUISettingsListener(new UISettingsListener() {
+ @Override
public void uiSettingsChanged(UISettings source) {
updateTabBorder();
}
@@ -354,6 +360,7 @@
myTab = tab;
}
+ @Override
public void putInfo(@NotNull Map<String, String> info) {
info.put("editorTab", myTab.getText());
}
@@ -387,6 +394,7 @@
return tab.getComponent();
}
+ @Override
public void dispose() {
}
@@ -409,6 +417,7 @@
e.getPresentation().setText("Close. Alt-click to close others.");
}
+ @Override
public void actionPerformed(final AnActionEvent e) {
final FileEditorManagerEx mgr = FileEditorManagerEx.getInstanceEx(myProject);
EditorWindow window;
@@ -434,6 +443,7 @@
}
private class MyDataProvider implements DataProvider {
+ @Override
public Object getData(@NonNls final String dataId) {
if (PlatformDataKeys.PROJECT.is(dataId)) {
return myProject;
@@ -464,6 +474,7 @@
}
}
+ @Override
public void close() {
TabInfo selected = myTabs.getTargetInfo();
if (selected == null) return;
@@ -533,6 +544,7 @@
}
private class MySwitchProvider implements SwitchProvider {
+ @Override
public List<SwitchTarget> getTargets(final boolean onlyVisible, boolean originalProvider) {
final ArrayList<SwitchTarget> result = new ArrayList<SwitchTarget>();
TabInfo selected = myTabs.getSelectedInfo();
@@ -552,6 +564,7 @@
return result;
}
+ @Override
public SwitchTarget getCurrentTarget() {
TabInfo selected = myTabs.getSelectedInfo();
final Ref<SwitchTarget> targetRef = new Ref<SwitchTarget>();
@@ -572,10 +585,12 @@
return targetRef.get();
}
+ @Override
public JComponent getComponent() {
return null;
}
+ @Override
public boolean isCycleRoot() {
return false;
}
@@ -589,7 +604,7 @@
@Override
public void dragOutStarted(MouseEvent mouseEvent, TabInfo info) {
final TabInfo previousSelection = info.getPreviousSelection();
- final Image img = myTabs.getComponentImage(info);
+ final Image img = JBTabsImpl.getComponentImage(info);
info.setHidden(true);
if (previousSelection != null) {
myTabs.select(previousSelection, true);
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
index 752e23d..4207cab 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
@@ -161,7 +161,7 @@
boolean editorToTheDown = false;
Splitter splitter = (Splitter)parent;
-
+
boolean vertical = splitter.getOrientation();
if (vertical && splitter.getFirstComponent() == c) {
editorToTheDown = true;
@@ -172,7 +172,7 @@
if (splitter.getSecondComponent() == c) editorToTheLeft = true;
}
-
+
//Frame frame = (Frame) SwingUtilities.getAncestorOfClass(Frame.class, c);
//if (frame instanceof IdeFrame) {
// Project project = ((IdeFrame)frame).getProject();
@@ -218,10 +218,10 @@
int bottom = editorToTheDown ? 1 : 0;
return new Insets(0, left, bottom, right);
}
-
+
return new Insets(0, 0, 0, 0);
}
-
+
@Nullable
private static Splitter nextOuterSplitter(Component c) {
Container parent = c.getParent();
@@ -290,6 +290,7 @@
public void closeFile(final VirtualFile file, final boolean unsplit, final boolean transferFocus) {
final FileEditorManagerImpl editorManager = getManager();
editorManager.runChange(new FileEditorManagerChange() {
+ @Override
public void run(EditorsSplitters splitters) {
final List<EditorWithProviderComposite> editors = splitters.findEditorComposites(file);
if (editors.isEmpty()) return;
@@ -308,6 +309,7 @@
myRemovedTabs.push(Pair.create(file.getUrl(), componentIndex));
final ActionCallback removeTab = myTabbedPane.removeTabAt(componentIndex, indexToSelect, transferFocus);
final Runnable disposer = new Runnable() {
+ @Override
public void run() {
editorManager.disposeComposite(editor);
}
@@ -378,11 +380,11 @@
return histFileIndex;
}
}
- } else
+ } else
if (uiSettings.ACTIVATE_RIGHT_EDITOR_ON_CLOSE && (fileIndex + 1 < myTabbedPane.getTabCount())) {
return fileIndex + 1;
}
-
+
// by default select previous neighbour
if (fileIndex > 0) {
return fileIndex - 1;
@@ -553,6 +555,7 @@
return myWindow;
}
+ @Override
public Object getData(String dataId) {
if (PlatformDataKeys.VIRTUAL_FILE.is(dataId)){
final VirtualFile virtualFile = myEditor.getFile();
@@ -570,6 +573,7 @@
super(window, editor);
}
+ @Override
public Object getData(String dataId) {
// this is essential for ability to close opened file
if (DATA_KEY.is(dataId)){
@@ -636,6 +640,7 @@
final int index = findFileIndex(editor.getFile());
if (index != -1) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
public void run() {
myTabbedPane.setSelectedIndex(index, focusEditor);
}
@@ -663,12 +668,12 @@
if (initialIndex == null) {
int selectedIndex = myTabbedPane.getSelectedIndex();
if (selectedIndex >= 0) {
- indexToInsert = UISettings.getInstance().ACTIVATE_RIGHT_EDITOR_ON_CLOSE ? selectedIndex : selectedIndex + 1;
+ indexToInsert = UISettings.getInstance().ACTIVATE_RIGHT_EDITOR_ON_CLOSE ? selectedIndex : selectedIndex + 1;
}
} else {
indexToInsert = initialIndex;
}
-
+
final VirtualFile file = editor.getFile();
final Icon template = AllIcons.FileTypes.Text;
myTabbedPane.insertTab(file, new EmptyIcon(template.getIconWidth(), template.getIconHeight()), new TComp(this, editor), null, indexToInsert);
@@ -709,7 +714,7 @@
myPanel.setOpaque(false);
myPanel.setBorder(new AdaptiveBorder());
myPanel.setOpaque(false);
-
+
final Splitter splitter = new Splitter(orientation == JSplitPane.VERTICAL_SPLIT, 0.5f, 0.1f, 0.9f);
final EditorWindow res = new EditorWindow(myOwner);
if (myTabbedPane != null) {
@@ -772,7 +777,7 @@
/**
* Tries to setup caret and viewport for the given editor from the selected one.
- *
+ *
* @param toSync editor to setup caret and viewport for
*/
private void syncCaretIfPossible(@Nullable FileEditor[] toSync) {
@@ -809,6 +814,7 @@
scrollingModel.scrollVertically(scrollOffset);
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
if (!editor.isDisposed()) {
scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE);
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java
index 6f10c4a..f3ccbef 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWithProviderComposite.java
@@ -47,6 +47,7 @@
return myProviders;
}
+ @Override
public boolean isModified() {
final FileEditor [] editors = getEditors ();
for (FileEditor editor : editors) {
@@ -57,6 +58,7 @@
return false;
}
+ @Override
@NotNull
public Pair<FileEditor, FileEditorProvider> getSelectedEditorWithProvider() {
LOG.assertTrue(myEditors.length > 0, myEditors.length);
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
index db07ac7..381daf8 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
@@ -479,6 +479,7 @@
myFilesToUpdateIconsFor.add(file);
myIconUpdaterAlarm.cancelAllRequests();
myIconUpdaterAlarm.addRequest(new Runnable() {
+ @Override
public void run() {
if (myManager.getProject().isDisposed()) return;
for (VirtualFile file : myFilesToUpdateIconsFor) {
@@ -650,6 +651,7 @@
}
private final class MyFocusTraversalPolicy extends IdeFocusTraversalPolicy {
+ @Override
public final Component getDefaultComponentImpl(final Container focusCycleRoot) {
if (myCurrentWindow != null) {
final EditorWithProviderComposite selectedEditor = myCurrentWindow.getSelectedEditor();
@@ -708,6 +710,7 @@
final EditorWithProviderComposite newEditor = window != null? window.getSelectedEditor() : null;
Runnable fireRunnable = new Runnable() {
+ @Override
public void run() {
getManager().fireSelectionChanged(newEditor);
}
@@ -824,6 +827,7 @@
}
private final class MyFocusWatcher extends FocusWatcher {
+ @Override
protected void focusedComponentChanged(final Component component, final AWTEvent cause) {
EditorWindow newWindow = null;
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
index bdafe4d..f31f4b4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
@@ -159,6 +159,7 @@
//-------------------------------------------------------------------------------
+ @Override
public JComponent getComponent() {
initUI();
return myPanels;
@@ -279,6 +280,7 @@
}
}
+ @Override
public JComponent getPreferredFocusedComponent() {
assertReadAccess();
final EditorWindow window = getSplitters().getCurrentWindow();
@@ -312,6 +314,7 @@
return FileUtil.getLocationRelativeToUserHome(file.getPresentableUrl());
}
+ @Override
public void updateFilePresentation(@NotNull VirtualFile file) {
if (!isFileOpen(file)) return;
@@ -357,10 +360,12 @@
// Queue here is to prevent title flickering when tab is being closed and two events arriving: with component==null and component==next focused tab
// only the last event makes sense to handle
myQueue.queue(new Update("UpdateFileName " + (file == null ? "" : file.getPath())) {
+ @Override
public boolean isExpired() {
return myProject.isDisposed() || !myProject.isOpen() || (file == null ? super.isExpired() : !file.isValid());
}
+ @Override
public void run() {
Set<EditorsSplitters> all = getAllSplitters();
for (EditorsSplitters each : all) {
@@ -373,6 +378,7 @@
//-------------------------------------------------------
+ @Override
public VirtualFile getFile(@NotNull final FileEditor editor) {
final EditorComposite editorComposite = getEditorComposite(editor);
if (editorComposite != null) {
@@ -381,6 +387,7 @@
return null;
}
+ @Override
public void unsplitWindow() {
final EditorWindow currentWindow = getActiveSplitters(true).getResult().getCurrentWindow();
if (currentWindow != null) {
@@ -388,6 +395,7 @@
}
}
+ @Override
public void unsplitAllWindow() {
final EditorWindow currentWindow = getActiveSplitters(true).getResult().getCurrentWindow();
if (currentWindow != null) {
@@ -407,6 +415,7 @@
return getWindowSplitCount() > 1;
}
+ @Override
@NotNull
public EditorWindow[] getWindows() {
ArrayList<EditorWindow> windows = new ArrayList<EditorWindow>();
@@ -419,6 +428,7 @@
return windows.toArray(new EditorWindow[windows.size()]);
}
+ @Override
public EditorWindow getNextWindow(@NotNull final EditorWindow window) {
final EditorWindow[] windows = getSplitters().getOrderedWindows();
for (int i = 0; i != windows.length; ++i) {
@@ -430,6 +440,7 @@
return null;
}
+ @Override
public EditorWindow getPrevWindow(@NotNull final EditorWindow window) {
final EditorWindow[] windows = getSplitters().getOrderedWindows();
for (int i = 0; i != windows.length; ++i) {
@@ -441,6 +452,7 @@
return null;
}
+ @Override
public void createSplitter(final int orientation, @Nullable final EditorWindow window) {
// window was available from action event, for example when invoked from the tab menu of an editor that is not the 'current'
if (window != null) {
@@ -455,6 +467,7 @@
}
}
+ @Override
public void changeSplitterOrientation() {
final EditorWindow currentWindow = getSplitters().getCurrentWindow();
if (currentWindow != null) {
@@ -463,6 +476,7 @@
}
+ @Override
public void flipTabs() {
/*
if (myTabs == null) {
@@ -480,6 +494,7 @@
myPanels.revalidate();
}
+ @Override
public boolean tabsMode() {
return false;
}
@@ -492,20 +507,24 @@
}
+ @Override
public boolean isInSplitter() {
final EditorWindow currentWindow = getSplitters().getCurrentWindow();
return currentWindow != null && currentWindow.inSplitter();
}
+ @Override
public boolean hasOpenedFile() {
final EditorWindow currentWindow = getSplitters().getCurrentWindow();
return currentWindow != null && currentWindow.getSelectedEditor() != null;
}
+ @Override
public VirtualFile getCurrentFile() {
return getActiveSplitters(true).getResult().getCurrentFile();
}
+ @Override
@NotNull
public AsyncResult<EditorWindow> getActiveWindow() {
return _getActiveWindow(false);
@@ -524,10 +543,12 @@
return result;
}
+ @Override
public EditorWindow getCurrentWindow() {
return _getActiveWindow(true).getResult();
}
+ @Override
public void setCurrentWindow(final EditorWindow window) {
getActiveSplitters(true).getResult().setCurrentWindow(window, true);
}
@@ -536,6 +557,7 @@
assertDispatchThread();
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
+ @Override
public void run() {
if (window.isFileOpen(file)) {
window.closeFile(file, true, transferFocus);
@@ -552,12 +574,14 @@
removeSelectionRecord(file, window);
}
+ @Override
public void closeFile(@NotNull final VirtualFile file, @NotNull final EditorWindow window) {
closeFile(file, window, true);
}
//============================= EditorManager methods ================================
+ @Override
public void closeFile(@NotNull final VirtualFile file) {
closeFile(file, true, false);
}
@@ -571,6 +595,7 @@
}
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
+ @Override
public void run() {
closeFileImpl(file, moveFocus, closeAllCopies);
}
@@ -582,6 +607,7 @@
private void closeFileImpl(@NotNull final VirtualFile file, final boolean moveFocus, boolean closeAllCopies) {
assertDispatchThread();
runChange(new FileEditorManagerChange() {
+ @Override
public void run(EditorsSplitters splitters) {
splitters.closeFile(file, moveFocus);
}
@@ -590,6 +616,7 @@
//-------------------------------------- Open File ----------------------------------------
+ @Override
@NotNull
public Pair<FileEditor[], FileEditorProvider[]> openFileWithProviders(@NotNull final VirtualFile file,
final boolean focusEditor,
@@ -697,6 +724,7 @@
final boolean focusEditor) {
final Ref<Pair<FileEditor[], FileEditorProvider[]>> result = new Ref<Pair<FileEditor[], FileEditorProvider[]>>();
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
+ @Override
public void run() {
result.set(openFileImpl3(window, file, focusEditor, null, true));
}
@@ -711,7 +739,6 @@
* invalid file become selected. That's why we do not require that
* passed file is valid.
* @param entry map between FileEditorProvider and FileEditorState. If this parameter
- * @param current
*/
@NotNull
Pair<FileEditor[], FileEditorProvider[]> openFileImpl3(@NotNull final EditorWindow window,
@@ -757,6 +784,7 @@
providers = editorProviderManager.getProviders(myProject, file);
if (DumbService.getInstance(myProject).isDumb()) {
final List<FileEditorProvider> dumbAware = ContainerUtil.findAll(providers, new Condition<FileEditorProvider>() {
+ @Override
public boolean value(FileEditorProvider fileEditorProvider) {
return DumbService.isDumbAware(fileEditorProvider);
}
@@ -873,6 +901,7 @@
window.getOwner().afterFileOpen(file);
UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
public void run() {
newSelectedComposite.getSelectedEditor().selectNotify();
}
@@ -1008,6 +1037,7 @@
return newComposite;
}
+ @Override
@NotNull
public List<FileEditor> openEditor(@NotNull final OpenFileDescriptor descriptor, final boolean focusEditor) {
assertDispatchThread();
@@ -1021,6 +1051,7 @@
final List<FileEditor> result = new ArrayList<FileEditor>();
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
+ @Override
public void run() {
VirtualFile file = descriptor.getFile();
final FileEditor[] editors = openFile(file, focusEditor, !descriptor.isUseCurrentWindow());
@@ -1075,11 +1106,13 @@
}
}
+ @Override
@NotNull
public Project getProject() {
return myProject;
}
+ @Override
@Nullable
public Editor openTextEditor(@NotNull final OpenFileDescriptor descriptor, final boolean focusEditor) {
final Collection<FileEditor> fileEditors = openEditor(descriptor, focusEditor);
@@ -1098,6 +1131,7 @@
return editor;
}
+ @Override
public Editor getSelectedTextEditor() {
assertReadAccess();
@@ -1113,10 +1147,12 @@
}
+ @Override
public boolean isFileOpen(@NotNull final VirtualFile file) {
return !getEditorComposites(file).isEmpty();
}
+ @Override
@NotNull
public VirtualFile[] getOpenFiles() {
HashSet<VirtualFile> openFiles = new HashSet<VirtualFile>();
@@ -1127,6 +1163,7 @@
return VfsUtilCore.toVirtualFileArray(openFiles);
}
+ @Override
@NotNull
public VirtualFile[] getSelectedFiles() {
HashSet<VirtualFile> selectedFiles = new HashSet<VirtualFile>();
@@ -1137,6 +1174,7 @@
return VfsUtilCore.toVirtualFileArray(selectedFiles);
}
+ @Override
@NotNull
public FileEditor[] getSelectedEditors() {
HashSet<FileEditor> selectedEditors = new HashSet<FileEditor>();
@@ -1147,12 +1185,14 @@
return selectedEditors.toArray(new FileEditor[selectedEditors.size()]);
}
+ @Override
@NotNull
public EditorsSplitters getSplitters() {
EditorsSplitters active = getActiveSplitters(true).getResult();
return active == null ? getMainSplitters() : active;
}
+ @Override
@Nullable
public FileEditor getSelectedEditor(@NotNull final VirtualFile file) {
final Pair<FileEditor, FileEditorProvider> selectedEditorWithProvider = getSelectedEditorWithProvider(file);
@@ -1160,6 +1200,7 @@
}
+ @Override
@Nullable
public Pair<FileEditor, FileEditorProvider> getSelectedEditorWithProvider(@NotNull VirtualFile file) {
if (file instanceof VirtualFileWindow) file = ((VirtualFileWindow)file).getDelegate();
@@ -1172,6 +1213,7 @@
return composites.isEmpty() ? null : composites.get(0).getSelectedEditorWithProvider();
}
+ @Override
@NotNull
public Pair<FileEditor[], FileEditorProvider[]> getEditorsWithProviders(@NotNull final VirtualFile file) {
assertReadAccess();
@@ -1190,6 +1232,7 @@
}
}
+ @Override
@NotNull
public FileEditor[] getEditors(@NotNull VirtualFile file) {
assertReadAccess();
@@ -1240,6 +1283,7 @@
return result;
}
+ @Override
@NotNull
public FileEditor[] getAllEditors() {
assertReadAccess();
@@ -1255,14 +1299,17 @@
return result.toArray(new FileEditor[result.size()]);
}
+ @Override
public void showEditorAnnotation(@NotNull FileEditor editor, @NotNull JComponent annotationComponent) {
addTopComponent(editor, annotationComponent);
}
+ @Override
public void removeEditorAnnotation(@NotNull FileEditor editor, @NotNull JComponent annotationComponent) {
removeTopComponent(editor, annotationComponent);
}
+ @Override
public void addTopComponent(@NotNull final FileEditor editor, @NotNull final JComponent component) {
final EditorComposite composite = getEditorComposite(editor);
if (composite != null) {
@@ -1270,6 +1317,7 @@
}
}
+ @Override
public void removeTopComponent(@NotNull final FileEditor editor, @NotNull final JComponent component) {
final EditorComposite composite = getEditorComposite(editor);
if (composite != null) {
@@ -1277,6 +1325,7 @@
}
}
+ @Override
public void addBottomComponent(@NotNull final FileEditor editor, @NotNull final JComponent component) {
final EditorComposite composite = getEditorComposite(editor);
if (composite != null) {
@@ -1284,6 +1333,7 @@
}
}
+ @Override
public void removeBottomComponent(@NotNull final FileEditor editor, @NotNull final JComponent component) {
final EditorComposite composite = getEditorComposite(editor);
if (composite != null) {
@@ -1293,20 +1343,24 @@
private final MessageListenerList<FileEditorManagerListener> myListenerList;
+ @Override
public void addFileEditorManagerListener(@NotNull final FileEditorManagerListener listener) {
myListenerList.add(listener);
}
+ @Override
public void addFileEditorManagerListener(@NotNull final FileEditorManagerListener listener, @NotNull final Disposable parentDisposable) {
myListenerList.add(listener, parentDisposable);
}
+ @Override
public void removeFileEditorManagerListener(@NotNull final FileEditorManagerListener listener) {
myListenerList.remove(listener);
}
// ProjectComponent methods
+ @Override
public void projectOpened() {
//myFocusWatcher.install(myWindows.getComponent ());
getMainSplitters().startListeningFocus();
@@ -1336,16 +1390,20 @@
UISettings.getInstance().addUISettingsListener(myUISettingsListener, myProject);
StartupManager.getInstance(myProject).registerPostStartupActivity(new DumbAwareRunnable() {
+ @Override
public void run() {
setTabsMode(UISettings.getInstance().EDITOR_TAB_PLACEMENT != UISettings.TABS_NONE);
ToolWindowManager.getInstance(myProject).invokeLater(new Runnable() {
+ @Override
public void run() {
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
+ @Override
public void run() {
LaterInvocator.invokeLater(new Runnable() {
+ @Override
public void run() {
long currentTime = System.nanoTime();
Long startTime = myProject.getUserData(ProjectImpl.CREATION_TIME);
@@ -1364,6 +1422,7 @@
});
}
+ @Override
public void projectClosed() {
//myFocusWatcher.deinstall(myWindows.getComponent ());
getMainSplitters().dispose();
@@ -1375,23 +1434,28 @@
// BaseCompomemnt methods
+ @Override
@NotNull
public String getComponentName() {
return FILE_EDITOR_MANAGER;
}
+ @Override
public void initComponent() {
}
+ @Override
public void disposeComponent() { /* really do nothing */ }
//JDOMExternalizable methods
+ @Override
public void writeExternal(final Element element) {
getMainSplitters().writeExternal(element);
}
+ @Override
public void readExternal(final Element element) {
getMainSplitters().readExternal(element);
}
@@ -1481,6 +1545,7 @@
return new Trinity<VirtualFile, FileEditor, FileEditorProvider>(file, editor, provider);
}
+ @Override
public boolean isChanged(@NotNull final EditorComposite editor) {
final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject);
if (fileStatusManager != null) {
@@ -1559,6 +1624,7 @@
* Closes deleted files. Closes file which are in the deleted directories.
*/
private final class MyVirtualFileListener extends VirtualFileAdapter {
+ @Override
public void beforeFileDeletion(VirtualFileEvent e) {
assertDispatchThread();
@@ -1573,6 +1639,7 @@
}
}
+ @Override
public void propertyChanged(VirtualFilePropertyEvent e) {
if (VirtualFile.PROP_NAME.equals(e.getPropertyName())) {
assertDispatchThread();
@@ -1602,6 +1669,7 @@
}
}
+ @Override
public void fileMoved(VirtualFileMoveEvent e) {
final VirtualFile file = e.getFile();
final VirtualFile[] openFiles = getOpenFiles();
@@ -1626,11 +1694,13 @@
return true;
}
+ @Override
public boolean isInsideChange() {
return getSplitters().isInsideChange();
}
private final class MyEditorPropertyChangeListener implements PropertyChangeListener {
+ @Override
public void propertyChange(final PropertyChangeEvent e) {
assertDispatchThread();
@@ -1662,6 +1732,7 @@
* Gets events from VCS and updates color of myEditor tabs
*/
private final class MyFileStatusListener implements FileStatusListener {
+ @Override
public void fileStatusesChanged() { // update color of all open files
assertDispatchThread();
LOG.debug("FileEditorManagerImpl.MyFileStatusListener.fileStatusesChanged()");
@@ -1670,6 +1741,7 @@
final VirtualFile file = openFiles[i];
LOG.assertTrue(file != null);
ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
public void run() {
if (LOG.isDebugEnabled()) {
LOG.debug("updating file status in tab for " + file.getPath());
@@ -1680,6 +1752,7 @@
}
}
+ @Override
public void fileStatusChanged(@NotNull final VirtualFile file) { // update color of the file (if necessary)
assertDispatchThread();
if (isFileOpen(file)) {
@@ -1710,6 +1783,7 @@
}
private class MyRootsListener extends ModuleRootAdapter {
+ @Override
public void rootsChanged(ModuleRootEvent event) {
EditorFileSwapper[] swappers = Extensions.getExtensions(EditorFileSwapper.EP_NAME);
@@ -1762,6 +1836,7 @@
* and EDITOR_TAB_LIMIT, etc values.
*/
private final class MyUISettingsListener implements UISettingsListener {
+ @Override
public void uiSettingsChanged(final UISettings source) {
assertDispatchThread();
setTabsMode(source.EDITOR_TAB_PLACEMENT != UISettings.TABS_NONE && !UISettings.getInstance().PRESENTATION_MODE);
@@ -1790,6 +1865,7 @@
}
}
+ @Override
public void closeAllFiles() {
final VirtualFile[] openFiles = getSplitters().getOpenFiles();
for (VirtualFile openFile : openFiles) {
@@ -1797,6 +1873,7 @@
}
}
+ @Override
@NotNull
public VirtualFile[] getSiblings(@NotNull VirtualFile file) {
return getOpenFiles();
@@ -1804,6 +1881,7 @@
protected void queueUpdateFile(final VirtualFile file) {
myQueue.queue(new Update(file) {
+ @Override
public void run() {
if (isFileOpen(file)) {
updateFileIcon(file);
@@ -1815,6 +1893,7 @@
});
}
+ @Override
public EditorsSplitters getSplittersFor(Component c) {
EditorsSplitters splitters = null;
DockContainer dockContainer = myDockManager.getContainerFor(c);
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorProviderManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorProviderManagerImpl.java
index c363256..9483073 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorProviderManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorProviderManagerImpl.java
@@ -57,10 +57,12 @@
public FileEditorProviderManagerImpl(FileEditorProvider[] providers) {
Extensions.getRootArea().getExtensionPoint(FileEditorProvider.EP_FILE_EDITOR_PROVIDER).addExtensionPointListener(
new ExtensionPointListener<FileEditorProvider>() {
+ @Override
public void extensionAdded(@NotNull final FileEditorProvider extension, @Nullable final PluginDescriptor pluginDescriptor) {
registerProvider(extension);
}
+ @Override
public void extensionRemoved(@NotNull final FileEditorProvider extension, @Nullable final PluginDescriptor pluginDescriptor) {
unregisterProvider(extension);
}
@@ -74,6 +76,7 @@
public FileEditorProviderManagerImpl() {
}
+ @Override
@NotNull
public synchronized FileEditorProvider[] getProviders(@NotNull final Project project, @NotNull final VirtualFile file){
// Collect all possible editors
@@ -113,6 +116,7 @@
}
}
+ @Override
@Nullable
public synchronized FileEditorProvider getProvider(@NotNull String editorTypeId){
for(int i=myProviders.size()-1;i>=0;i--){
@@ -211,6 +215,7 @@
: Double.MAX_VALUE;
}
+ @Override
public int compare(FileEditorProvider provider1, FileEditorProvider provider2) {
final int i1 = provider1.getPolicy().ordinal();
final int i2 = provider2.getPolicy().ordinal();
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/MoveEditorToOppositeTabGroupAction.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/MoveEditorToOppositeTabGroupAction.java
index 557c65b..0fe8fef 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/MoveEditorToOppositeTabGroupAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/MoveEditorToOppositeTabGroupAction.java
@@ -27,6 +27,7 @@
*/
public class MoveEditorToOppositeTabGroupAction extends AnAction implements DumbAware {
+ @Override
public void actionPerformed(final AnActionEvent event) {
final DataContext dataContext = event.getDataContext();
final VirtualFile vFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext);
@@ -46,6 +47,7 @@
}
}
+ @Override
public void update(AnActionEvent e) {
final Presentation presentation = e.getPresentation();
final DataContext dataContext = e.getDataContext();
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/SelectNextEditorTabAction.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/SelectNextEditorTabAction.java
index 15dfa39..63c44ab 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/SelectNextEditorTabAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/SelectNextEditorTabAction.java
@@ -26,6 +26,7 @@
// The only purpose of this action is to serve as placeholder for assigning keyboard shortcuts.
// For actual tab switching code, see EditorComposite constructor.
public class SelectNextEditorTabAction extends AnAction implements DumbAware {
+ @Override
public void actionPerformed(final AnActionEvent e) {
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/SelectPreviousEditorTabAction.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/SelectPreviousEditorTabAction.java
index 3f17ddf..d601179 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/SelectPreviousEditorTabAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/SelectPreviousEditorTabAction.java
@@ -26,6 +26,7 @@
// The only purpose of this action is to serve as placeholder for assigning keyboard shortcuts.
// For actual tab switching code, see EditorComposite constructor.
public class SelectPreviousEditorTabAction extends AnAction implements DumbAware {
+ @Override
public void actionPerformed(final AnActionEvent e) {
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/TrailingSpacesStripper.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/TrailingSpacesStripper.java
index 7958c1c..db45506e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/TrailingSpacesStripper.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/TrailingSpacesStripper.java
@@ -88,6 +88,7 @@
@Override
public void run() {
CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
+ @Override
public void run() {
if (CharArrayUtil.containsOnlyWhiteSpaces(content.subSequence(start, end)) && doStrip) {
document.deleteString(start, end);
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/WaverGraphicsDecorator.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/WaverGraphicsDecorator.java
index 52e9d3a..e9e1968 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/WaverGraphicsDecorator.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/WaverGraphicsDecorator.java
@@ -57,275 +57,342 @@
}
}
+ @Override
public void draw(final Shape s) {
myOriginal.draw(s);
}
+ @Override
public boolean drawImage(final Image img, final AffineTransform xform, final ImageObserver obs) {
return myOriginal.drawImage(img, xform, obs);
}
+ @Override
public void drawImage(final BufferedImage img, final BufferedImageOp op, final int x, final int y) {
myOriginal.drawImage(img, op, x, y);
}
+ @Override
public void drawRenderedImage(final RenderedImage img, final AffineTransform xform) {
myOriginal.drawRenderedImage(img, xform);
}
+ @Override
public void drawRenderableImage(final RenderableImage img, final AffineTransform xform) {
myOriginal.drawRenderableImage(img, xform);
}
+ @Override
public void drawString(final String str, final int x, final int y) {
myOriginal.drawString(str, x, y);
drawWave(str, x, y);
}
+ @Override
public void drawString(final String s, final float x, final float y) {
myOriginal.drawString(s, x, y);
drawWave(s, (int)x, (int)y);
}
+ @Override
public void drawString(final AttributedCharacterIterator iterator, final int x, final int y) {
myOriginal.drawString(iterator, x, y);
//TODO: drawWave
}
+ @Override
public void drawString(final AttributedCharacterIterator iterator, final float x, final float y) {
myOriginal.drawString(iterator, x, y);
//TODO: drawWave
}
+ @Override
public void drawGlyphVector(final GlyphVector g, final float x, final float y) {
myOriginal.drawGlyphVector(g, x, y);
//TODO: drawWave
}
+ @Override
public void fill(final Shape s) {
myOriginal.fill(s);
}
+ @Override
public boolean hit(final Rectangle rect, final Shape s, final boolean onStroke) {
return myOriginal.hit(rect, s, onStroke);
}
+ @Override
public GraphicsConfiguration getDeviceConfiguration() {
return myOriginal.getDeviceConfiguration();
}
+ @Override
public void setComposite(final Composite comp) {
myOriginal.setComposite(comp);
}
+ @Override
public void setPaint(final Paint paint) {
myOriginal.setPaint(paint);
}
+ @Override
public void setStroke(final Stroke s) {
myOriginal.setStroke(s);
}
+ @Override
public void setRenderingHint(final RenderingHints.Key hintKey, final Object hintValue) {
myOriginal.setRenderingHint(hintKey, hintValue);
}
+ @Override
public Object getRenderingHint(final RenderingHints.Key hintKey) {
return myOriginal.getRenderingHint(hintKey);
}
+ @Override
public void setRenderingHints(final Map<?, ?> hints) {
myOriginal.setRenderingHints(hints);
}
+ @Override
public void addRenderingHints(final Map<?, ?> hints) {
myOriginal.addRenderingHints(hints);
}
+ @Override
public RenderingHints getRenderingHints() {
return myOriginal.getRenderingHints();
}
+ @Override
public void translate(final int x, final int y) {
myOriginal.translate(x, y);
}
+ @Override
public void translate(final double tx, final double ty) {
myOriginal.translate(tx, ty);
}
+ @Override
public void rotate(final double theta) {
myOriginal.rotate(theta);
}
+ @Override
public void rotate(final double theta, final double x, final double y) {
myOriginal.rotate(theta, x, y);
}
+ @Override
public void scale(final double sx, final double sy) {
myOriginal.scale(sx, sy);
}
+ @Override
public void shear(final double shx, final double shy) {
myOriginal.shear(shx, shy);
}
+ @Override
public void transform(final AffineTransform Tx) {
myOriginal.transform(Tx);
}
+ @Override
public void setTransform(final AffineTransform Tx) {
myOriginal.setTransform(Tx);
}
+ @Override
public AffineTransform getTransform() {
return myOriginal.getTransform();
}
+ @Override
public Paint getPaint() {
return myOriginal.getPaint();
}
+ @Override
public Composite getComposite() {
return myOriginal.getComposite();
}
+ @Override
public void setBackground(final Color color) {
myOriginal.setBackground(color);
}
+ @Override
public Color getBackground() {
return myOriginal.getBackground();
}
+ @Override
public Stroke getStroke() {
return myOriginal.getStroke();
}
+ @Override
public void clip(final Shape s) {
myOriginal.clip(s);
}
+ @Override
public FontRenderContext getFontRenderContext() {
return myOriginal.getFontRenderContext();
}
+ @Override
public Graphics create() {
return new WaverGraphicsDecorator((Graphics2D)myOriginal.create(), myWaveColor);
}
+ @Override
public Color getColor() {
return myOriginal.getColor();
}
+ @Override
public void setColor(final Color c) {
myOriginal.setColor(c);
}
+ @Override
public void setPaintMode() {
myOriginal.setPaintMode();
}
+ @Override
public void setXORMode(final Color c1) {
myOriginal.setXORMode(c1);
}
+ @Override
public Font getFont() {
return myOriginal.getFont();
}
+ @Override
public void setFont(final Font font) {
myOriginal.setFont(font);
}
+ @Override
public FontMetrics getFontMetrics(final Font f) {
return myOriginal.getFontMetrics(f);
}
+ @Override
public Rectangle getClipBounds() {
return myOriginal.getClipBounds();
}
+ @Override
public void clipRect(final int x, final int y, final int width, final int height) {
myOriginal.clipRect(x, y, width, height);
}
+ @Override
public void setClip(final int x, final int y, final int width, final int height) {
myOriginal.setClip(x, y, width, height);
}
+ @Override
public Shape getClip() {
return myOriginal.getClip();
}
+ @Override
public void setClip(final Shape clip) {
myOriginal.setClip(clip);
}
+ @Override
public void copyArea(final int x, final int y, final int width, final int height, final int dx, final int dy) {
myOriginal.copyArea(x, y, width, height, dx, dy);
}
+ @Override
public void drawLine(final int x1, final int y1, final int x2, final int y2) {
myOriginal.drawLine(x1, y1, x2, y2);
}
+ @Override
public void fillRect(final int x, final int y, final int width, final int height) {
myOriginal.fillRect(x, y, width, height);
}
+ @Override
public void clearRect(final int x, final int y, final int width, final int height) {
myOriginal.clearRect(x, y, width, height);
}
+ @Override
public void drawRoundRect(final int x, final int y, final int width, final int height, final int arcWidth, final int arcHeight) {
myOriginal.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
}
+ @Override
public void fillRoundRect(final int x, final int y, final int width, final int height, final int arcWidth, final int arcHeight) {
myOriginal.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
}
+ @Override
public void drawOval(final int x, final int y, final int width, final int height) {
myOriginal.drawOval(x, y, width, height);
}
+ @Override
public void fillOval(final int x, final int y, final int width, final int height) {
myOriginal.fillOval(x, y, width, height);
}
+ @Override
public void drawArc(final int x, final int y, final int width, final int height, final int startAngle, final int arcAngle) {
myOriginal.drawArc(x, y, width, height, startAngle, arcAngle);
}
+ @Override
public void fillArc(final int x, final int y, final int width, final int height, final int startAngle, final int arcAngle) {
myOriginal.fillArc(x, y, width, height, startAngle, arcAngle);
}
+ @Override
public void drawPolyline(final int[] xPoints, final int[] yPoints, final int nPoints) {
myOriginal.drawPolyline(xPoints, yPoints, nPoints);
}
+ @Override
public void drawPolygon(final int[] xPoints, final int[] yPoints, final int nPoints) {
myOriginal.drawPolygon(xPoints, yPoints, nPoints);
}
+ @Override
public void fillPolygon(final int[] xPoints, final int[] yPoints, final int nPoints) {
myOriginal.fillPolygon(xPoints, yPoints, nPoints);
}
+ @Override
public boolean drawImage(final Image img, final int x, final int y, final ImageObserver observer) {
return myOriginal.drawImage(img, x, y, observer);
}
+ @Override
public boolean drawImage(final Image img, final int x, final int y, final int width, final int height, final ImageObserver observer) {
return myOriginal.drawImage(img, x, y, width, height, observer);
}
+ @Override
public boolean drawImage(final Image img, final int x, final int y, final Color bgcolor, final ImageObserver observer) {
return myOriginal.drawImage(img, x, y, bgcolor, observer);
}
+ @Override
public boolean drawImage(final Image img,
final int x,
final int y,
@@ -336,6 +403,7 @@
return myOriginal.drawImage(img, x, y, width, height, bgcolor, observer);
}
+ @Override
public boolean drawImage(final Image img,
final int dx1,
final int dy1,
@@ -349,6 +417,7 @@
return myOriginal.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer);
}
+ @Override
public boolean drawImage(final Image img,
final int dx1,
final int dy1,
@@ -363,47 +432,58 @@
return myOriginal.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgcolor, observer);
}
+ @Override
public void dispose() {
//myOriginal.dispose();
}
+ @Override
public Rectangle getClipRect() {
return myOriginal.getClipRect();
}
+ @Override
public boolean hitClip(final int x, final int y, final int width, final int height) {
return myOriginal.hitClip(x, y, width, height);
}
+ @Override
public Rectangle getClipBounds(final Rectangle r) {
return myOriginal.getClipBounds(r);
}
+ @Override
public void fill3DRect(final int x, final int y, final int width, final int height, final boolean raised) {
myOriginal.fill3DRect(x, y, width, height, raised);
}
+ @Override
public void draw3DRect(final int x, final int y, final int width, final int height, final boolean raised) {
myOriginal.draw3DRect(x, y, width, height, raised);
}
+ @Override
public Graphics create(final int x, final int y, final int width, final int height) {
return new WaverGraphicsDecorator((Graphics2D)myOriginal.create(x, y, width, height), myWaveColor);
}
+ @Override
public void drawRect(final int x, final int y, final int width, final int height) {
myOriginal.drawRect(x, y, width, height);
}
+ @Override
public void drawPolygon(final Polygon p) {
myOriginal.drawPolygon(p);
}
+ @Override
public void fillPolygon(final Polygon p) {
myOriginal.fillPolygon(p);
}
+ @Override
public FontMetrics getFontMetrics() {
return myOriginal.getFontMetrics();
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditor.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditor.java
index ac57802..956998c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditor.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditor.java
@@ -47,11 +47,13 @@
myPanel = new RemoteFilePanel(project, virtualFile);
}
+ @Override
@NotNull
public JComponent getComponent() {
return myPanel.getMainPanel();
}
+ @Override
public JComponent getPreferredFocusedComponent() {
final TextEditor textEditor = myPanel.getFileEditor();
if (textEditor != null) {
@@ -60,11 +62,13 @@
return myPanel.getMainPanel();
}
+ @Override
@NotNull
public String getName() {
return "Http";
}
+ @Override
@NotNull
public Editor getEditor() {
final TextEditor fileEditor = myPanel.getFileEditor();
@@ -77,6 +81,7 @@
return myMockTextEditor;
}
+ @Override
@NotNull
public FileEditorState getState(@NotNull final FileEditorStateLevel level) {
final TextEditor textEditor = myPanel.getFileEditor();
@@ -86,6 +91,7 @@
return new TextEditorState();
}
+ @Override
public void setState(@NotNull final FileEditorState state) {
final TextEditor textEditor = myPanel.getFileEditor();
if (textEditor != null) {
@@ -93,30 +99,37 @@
}
}
+ @Override
public boolean isModified() {
return false;
}
+ @Override
public boolean isValid() {
return true;
}
+ @Override
public void selectNotify() {
myPanel.selectNotify();
}
+ @Override
public void deselectNotify() {
myPanel.deselectNotify();
}
+ @Override
public void addPropertyChangeListener(@NotNull final PropertyChangeListener listener) {
myPanel.addPropertyChangeListener(listener);
}
+ @Override
public void removePropertyChangeListener(@NotNull final PropertyChangeListener listener) {
myPanel.removePropertyChangeListener(listener);
}
+ @Override
public BackgroundEditorHighlighter getBackgroundHighlighter() {
final TextEditor textEditor = myPanel.getFileEditor();
if (textEditor != null) {
@@ -125,6 +138,7 @@
return null;
}
+ @Override
public boolean canNavigateTo(@NotNull Navigatable navigatable) {
final TextEditor textEditor = myPanel.getFileEditor();
if (textEditor != null) {
@@ -133,6 +147,7 @@
return false;
}
+ @Override
public void navigateTo(@NotNull Navigatable navigatable) {
final TextEditor textEditor = myPanel.getFileEditor();
if (textEditor != null) {
@@ -140,6 +155,7 @@
}
}
+ @Override
public <T> T getUserData(@NotNull Key<T> key) {
final TextEditor textEditor = myPanel.getFileEditor();
if (textEditor != null) {
@@ -148,6 +164,7 @@
return myUserDataHolder.getUserData(key);
}
+ @Override
public <T> void putUserData(@NotNull Key<T> key, @Nullable T value) {
final TextEditor textEditor = myPanel.getFileEditor();
if (textEditor != null) {
@@ -158,6 +175,7 @@
}
}
+ @Override
public FileEditorLocation getCurrentLocation() {
final TextEditor textEditor = myPanel.getFileEditor();
if (textEditor != null) {
@@ -166,6 +184,7 @@
return null;
}
+ @Override
public StructureViewBuilder getStructureViewBuilder() {
final TextEditor textEditor = myPanel.getFileEditor();
if (textEditor != null) {
@@ -174,6 +193,7 @@
return null;
}
+ @Override
public void dispose() {
if (myMockTextEditor != null) {
EditorFactory.getInstance().releaseEditor(myMockTextEditor);
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditorProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditorProvider.java
index 58a2f90..17354c7 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditorProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/HttpFileEditorProvider.java
@@ -32,32 +32,39 @@
* @author nik
*/
public class HttpFileEditorProvider implements FileEditorProvider, DumbAware {
+ @Override
public boolean accept(@NotNull final Project project, @NotNull final VirtualFile file) {
return file instanceof HttpVirtualFile && !file.isDirectory();
}
+ @Override
@NotNull
public FileEditor createEditor(@NotNull final Project project, @NotNull final VirtualFile file) {
- return new HttpFileEditor(project, (HttpVirtualFile)file);
+ return new HttpFileEditor(project, (HttpVirtualFile)file);
}
+ @Override
public void disposeEditor(@NotNull final FileEditor editor) {
Disposer.dispose(editor);
}
+ @Override
@NotNull
public FileEditorState readState(@NotNull final Element sourceElement, @NotNull final Project project, @NotNull final VirtualFile file) {
return new TextEditorState();
}
+ @Override
public void writeState(@NotNull final FileEditorState state, @NotNull final Project project, @NotNull final Element targetElement) {
}
+ @Override
@NotNull
public String getEditorTypeId() {
return "httpFileEditor";
}
+ @Override
@NotNull
public FileEditorPolicy getPolicy() {
return FileEditorPolicy.HIDE_DEFAULT_EDITOR;
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/FileDropHandler.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/FileDropHandler.java
index 5211c89..972ac67 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/FileDropHandler.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/FileDropHandler.java
@@ -45,10 +45,12 @@
}
+ @Override
public boolean canHandleDrop(final DataFlavor[] transferFlavors) {
return transferFlavors != null && FileCopyPasteUtil.isFileListFlavorSupported(transferFlavors);
}
+ @Override
public void handleDrop(@NotNull final Transferable t, @Nullable final Project project, EditorWindow editorWindow) {
if (project == null || !FileCopyPasteUtil.isFileListFlavorSupported(t)) {
return;
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/LargeFileEditorProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/LargeFileEditorProvider.java
index afaf715..cf3411b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/LargeFileEditorProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/LargeFileEditorProvider.java
@@ -36,6 +36,7 @@
*/
public class LargeFileEditorProvider implements FileEditorProvider, DumbAware {
+ @Override
public boolean accept(@NotNull Project project, @NotNull VirtualFile file) {
if (file.isDirectory() || !file.isValid()) {
return false;
@@ -43,28 +44,34 @@
return SingleRootFileViewProvider.isTooLargeForContentLoading(file);
}
+ @Override
@NotNull
public FileEditor createEditor(@NotNull Project project, @NotNull final VirtualFile file) {
return new LargeFileEditor(file);
}
+ @Override
public void disposeEditor(@NotNull FileEditor editor) {
Disposer.dispose(editor);
}
+ @Override
@NotNull
public FileEditorState readState(@NotNull Element element, @NotNull Project project, @NotNull VirtualFile file) {
return FileEditorState.INSTANCE;
}
+ @Override
public void writeState(@NotNull FileEditorState _state, @NotNull Project project, @NotNull Element element) {
}
+ @Override
@NotNull
public String getEditorTypeId() {
return "LargeFileEditor";
}
+ @Override
@NotNull
public FileEditorPolicy getPolicy() {
return FileEditorPolicy.NONE;
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredFileCache.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredFileCache.java
index d0ed91c..145aba5 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredFileCache.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredFileCache.java
@@ -16,7 +16,6 @@
package com.intellij.openapi.fileTypes.impl;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
@@ -35,11 +34,10 @@
* @author peter
*/
class IgnoredFileCache {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileTypes.impl.IgnoredFileCache");
private final BitSet myCheckedIds = new BitSet();
private final TIntHashSet myIgnoredIds = new TIntHashSet();
private final IgnoredPatternSet myIgnoredPatterns;
- private boolean myEnableCache = true;
+ private int myVfsEventNesting = 0;
IgnoredFileCache(IgnoredPatternSet ignoredPatterns) {
myIgnoredPatterns = ignoredPatterns;
@@ -48,17 +46,14 @@
@Override
public void before(@NotNull List<? extends VFileEvent> events) {
// during VFS event processing the system may be in inconsistent state, don't cache it
- if (!myEnableCache) {
- LOG.error("VFS before event received without a matching after: " + events);
- }
- myEnableCache = false;
+ myVfsEventNesting++;
clearCacheForChangedFiles(events);
}
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
clearCacheForChangedFiles(events);
- myEnableCache = true;
+ myVfsEventNesting--;
}
private void clearCacheForChangedFiles(List<? extends VFileEvent> events) {
@@ -98,7 +93,7 @@
}
boolean isFileIgnored(VirtualFile file) {
- if (!myEnableCache || !(file instanceof NewVirtualFile)) {
+ if (myVfsEventNesting == 0 || !(file instanceof NewVirtualFile)) {
return isFileIgnoredNoCache(file);
}
@@ -113,7 +108,7 @@
}
}
- boolean result = isFileIgnoredNoCache(file);;
+ boolean result = isFileIgnoredNoCache(file);
synchronized (myCheckedIds) {
myCheckedIds.set(id);
if (result) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java
index 50aee94..3fb8bcf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java
@@ -166,6 +166,29 @@
return myCurrentModalProgressCount.get() > 0;
}
+ @Override
+ public void runProcess(@NotNull final Runnable process, final ProgressIndicator progress) {
+ executeProcessUnderProgress(new Runnable(){
+ @Override
+ public void run() {
+ try {
+ if (progress != null && !progress.isRunning()) {
+ progress.start();
+ }
+ process.run();
+ maybeSleep();
+ }
+ finally {
+ if (progress != null && progress.isRunning()) {
+ progress.stop();
+ if (progress instanceof ProgressIndicatorEx) {
+ ((ProgressIndicatorEx)progress).processFinish();
+ }
+ }
+ }
+ }
+ },progress);
+ }
@Override
public <T> T runProcess(@NotNull final Computable<T> process, ProgressIndicator progress) throws ProcessCanceledException {
@@ -413,36 +436,6 @@
}
}
- @Override
- public void runProcess(@NotNull final Runnable process, final ProgressIndicator progress) {
- executeProcessUnderProgress(new Runnable(){
- @Override
- public void run() {
- synchronized (process) {
- process.notifyAll();
- }
- try {
- if (progress != null && !progress.isRunning()) {
- progress.start();
- }
- process.run();
- maybeSleep();
- }
- finally {
- if (progress != null && progress.isRunning()) {
- progress.stop();
- if (progress instanceof ProgressIndicatorEx) {
- ((ProgressIndicatorEx)progress).processFinish();
- }
- synchronized (process) {
- process.notifyAll();
- }
- }
- }
- }
- },progress);
- }
-
private abstract static class TaskContainer implements Runnable {
private final Task myTask;
diff --git a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
index 6693ca3..b616efd 100644
--- a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
@@ -26,7 +26,7 @@
import com.intellij.openapi.progress.*;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.ui.MessageType;
-import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.wm.AppIconScheme;
import com.intellij.openapi.wm.IdeFrame;
@@ -144,7 +144,7 @@
}
try {
final int size = runner.queryNeededFiles(indicator);
- if (application.isHeadlessEnvironment() || (size + runner.getNumberOfPendingUpdateJobs(indicator)) < 50) {
+ if (size + runner.getNumberOfPendingUpdateJobs(indicator) < 50) {
// If not that many files found, process them on the spot, avoiding entering dumb mode
// Consider number of pending tasks as well, because they may take noticeable time to process even if the number of files is small
try {
@@ -176,37 +176,38 @@
return;
}
// ok to test and set the flag like this, because the change is always done from dispatch thread
- final boolean wasDumb = myDumb;
- if (!wasDumb) {
- // always change dumb status inside write action.
- // This will ensure all active read actions are completed before the app goes dumb
- final Ref<Boolean> startFailure = new Ref<Boolean>(Boolean.FALSE);
- application.runWriteAction(new Runnable() {
- public void run() {
- myDumb = true;
- try {
- myPublisher.enteredDumbMode();
- }
- catch (Throwable e) {
- LOG.error(e);
- }
- finally {
- try {
- updateRunnable.run();
- }
- catch (Throwable e) {
- startFailure.set(Boolean.TRUE);
- LOG.error("Failed to start background index update task", e);
- }
- }
- }
- });
- if (startFailure.get()) {
- updateFinished();
- }
+ if (myDumb) {
+ myUpdatesQueue.addLast(updateRunnable);
}
else {
- myUpdatesQueue.addLast(updateRunnable);
+ // always change dumb status inside write action.
+ // This will ensure all active read actions are completed before the app goes dumb
+ boolean startSuccess =
+ application.runWriteAction(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ myDumb = true;
+ try {
+ myPublisher.enteredDumbMode();
+ }
+ catch (Throwable e) {
+ LOG.error(e);
+ }
+ finally {
+ try {
+ updateRunnable.run();
+ }
+ catch (Throwable e) {
+ LOG.error("Failed to start background index update task", e);
+ return false;
+ }
+ }
+ return true;
+ }
+ });
+ if (!startSuccess) {
+ updateFinished();
+ }
}
}
});
@@ -254,7 +255,7 @@
});
}
- private static final Ref<CacheUpdateRunner> NULL_ACTION = new Ref<CacheUpdateRunner>(null);
+ private static final CacheUpdateRunner NULL_ACTION = new CacheUpdateRunner(null,null);
public void waitForSmartMode() {
final Application application = ApplicationManager.getApplication();
@@ -389,14 +390,14 @@
}
}
- @Nullable
+ @Nullable
private CacheUpdateRunner getNextUpdateRunner() {
- final BlockingQueue<Ref<CacheUpdateRunner>> actionQueue = new LinkedBlockingQueue<Ref<CacheUpdateRunner>>();
+ final BlockingQueue<CacheUpdateRunner> actionQueue = new LinkedBlockingQueue<CacheUpdateRunner>();
UIUtil.invokeLaterIfNeeded(new DumbAwareRunnable() {
public void run() {
IndexUpdateRunnable nextRunnable = getNextUpdateFromQueue();
try {
- actionQueue.offer(nextRunnable == null ? NULL_ACTION : new Ref<CacheUpdateRunner>(nextRunnable.myAction));
+ actionQueue.offer(nextRunnable == null ? NULL_ACTION : nextRunnable.myAction);
}
finally {
if (nextRunnable == null) {
@@ -409,9 +410,9 @@
// try to obtain the next action or terminate if no actions left
while (!myProject.isDisposed()) {
try {
- Ref<CacheUpdateRunner> ref = actionQueue.poll(500L, TimeUnit.MILLISECONDS);
+ CacheUpdateRunner ref = actionQueue.poll(500L, TimeUnit.MILLISECONDS);
if (ref != null) {
- return ref.get();
+ return ref == NULL_ACTION ? null : ref;
}
}
catch (InterruptedException e) {
@@ -421,7 +422,7 @@
return null;
}
- @Nullable
+ @Nullable
private IndexUpdateRunnable getNextUpdateFromQueue() {
try {
return myUpdatesQueue.isEmpty()? null : myUpdatesQueue.pullFirst();
diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/ex/MessagesEx.java b/platform/platform-impl/src/com/intellij/openapi/ui/ex/MessagesEx.java
index 70e4870..543efbf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/ui/ex/MessagesEx.java
+++ b/platform/platform-impl/src/com/intellij/openapi/ui/ex/MessagesEx.java
@@ -23,6 +23,7 @@
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.UIBundle;
import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -52,34 +53,42 @@
return error(project, message, UIBundle.message("error.dialog.title"));
}
+ @NotNull
public static MessageInfo error(Project project, String message, String title) {
return new MessageInfo(project, message, title);
}
- public static abstract class BaseDialogInfo<ThisClass extends BaseDialogInfo> {
- private Project myProject;
+ public abstract static class BaseDialogInfo<ThisClass extends BaseDialogInfo> {
+ private final Project myProject;
private String myMessage;
private String myTitle;
private Icon myIcon;
- private String[] myOptions = new String[]{CommonBundle.getOkButtonText()};
+ private String[] myOptions = {CommonBundle.getOkButtonText()};
private int myDefaultOption = 0;
protected BaseDialogInfo(Project project) {
myProject = project;
}
- public BaseDialogInfo(Project project, String message, String title, Icon icon) {
+ public BaseDialogInfo(Project project, @NotNull String message, String title, Icon icon) {
this(project);
myMessage = message;
myTitle = title;
myIcon = icon;
}
- public ThisClass setTitle(String title) { myTitle = title; return getThis(); }
+ @NotNull
+ public ThisClass setTitle(String title) {
+ myTitle = title;
+ return getThis();
+ }
- public String getMessage() { return myMessage; }
+ public String getMessage() {
+ return myMessage;
+ }
- public ThisClass appendMessage(String message) {
+ @NotNull
+ public ThisClass appendMessage(@NotNull String message) {
myMessage += message;
return getThis();
}
@@ -89,11 +98,16 @@
myDefaultOption = defaultOption;
}
+ @NotNull
protected abstract ThisClass getThis();
- public ThisClass setIcon(Icon icon) { myIcon = icon; return getThis(); }
+ @NotNull
+ public ThisClass setIcon(Icon icon) {
+ myIcon = icon;
+ return getThis();
+ }
- public void setMessage(String message) {
+ public void setMessage(@NotNull String message) {
myMessage = message;
}
@@ -129,11 +143,11 @@
public void showLater() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
public void run() {
- if (ApplicationManager.getApplication().isDisposed()) return;
showNow();
}
- });
+ }, ApplicationManager.getApplication().getDisposed());
}
public int askYesNo() {
@@ -146,6 +160,8 @@
return showNow();
}
+ @NotNull
+ @Override
protected MessageInfo getThis() {
return this;
}
@@ -161,6 +177,8 @@
setOptions(new String[]{CommonBundle.getOkButtonText()}, 0);
}
+ @NotNull
+ @Override
public ChoiceInfo getThis() {
return this;
}
@@ -171,6 +189,7 @@
return getThis();
}
+ @Override
public UserInput askUser() {
ChooseDialog dialog = new ChooseDialog(getProject(), getMessage(), getTitle(), getIcon(), myChoises, myDefaultChoice, getOptions(), getDefaultOption());
dialog.setValidator(null);
@@ -209,12 +228,15 @@
setOptions(new String[]{CommonBundle.getOkButtonText(), CommonBundle.getCancelButtonText()}, 0);
}
+ @Override
public UserInput askUser() {
InputDialog dialog = new InputDialog(getProject(), getMessage(), getTitle(), getIcon(), myDefaultValue, null, getOptions(), getDefaultOption());
dialog.show();
return new UserInput(dialog.getTextField().getText(), dialog.getExitCode());
}
+ @NotNull
+ @Override
public InputInfo getThis() {
return this;
}
@@ -224,7 +246,7 @@
}
}
- public static abstract class BaseInputInfo<ThisClass extends BaseInputInfo> extends BaseDialogInfo<ThisClass> {
+ public abstract static class BaseInputInfo<ThisClass extends BaseInputInfo> extends BaseDialogInfo<ThisClass> {
public BaseInputInfo(Project project) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java
index e09e48c..8663013 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java
@@ -419,14 +419,7 @@
final DumbService.DumbModeListener dumbModeListener = new DumbService.DumbModeListener() {
@Override
public void enteredDumbMode() {
- for (final String id : getToolWindowIds()) {
- if (!myDumbAwareIds.contains(id)) {
- if (isToolWindowVisible(id)) {
- hideToolWindow(id, true);
- }
- getStripeButton(id).setEnabled(false);
- }
- }
+ disableStripeButtons();
}
@Override
@@ -443,7 +436,7 @@
public void run() {
registerToolWindowsFromBeans();
if (DumbService.getInstance(myProject).isDumb()) {
- dumbModeListener.enteredDumbMode();
+ disableStripeButtons();
}
}
});
@@ -459,6 +452,17 @@
}, myProject);
}
+ private void disableStripeButtons() {
+ for (final String id : getToolWindowIds()) {
+ if (!myDumbAwareIds.contains(id)) {
+ if (isToolWindowVisible(id)) {
+ hideToolWindow(id, true);
+ }
+ getStripeButton(id).setEnabled(false);
+ }
+ }
+ }
+
private JComponent createEditorComponent(Project project) {
return FrameEditorComponentProvider.EP.getExtensions()[0].createEditorComponent(project);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java
index caa0487..06b00ea 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java
@@ -244,7 +244,7 @@
@SuppressWarnings("SpellCheckingInspection")
public static void patchDetectedWm(String wmName) {
- if (X11 == null || Registry.is("idea.x11.skip.wm.patching")) return;
+ if (X11 == null || !Registry.is("ide.x11.override.wm")) return;
try {
if (wmName.startsWith("Mutter") || "Muffin".equals(wmName) || "GNOME Shell".equals(wmName)) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusPanel.java
index a1deb69..ad42294 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusPanel.java
@@ -95,7 +95,7 @@
StatusPanel() {
super(new BorderLayout());
- setOpaque(isOpaque() && !SystemInfo.isMac);
+ setOpaque(false);
myTextPanel.setBorder(new EmptyBorder(0, 5, 0, 0));
new ClickListener() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java
index 1ebb011..225bbf0 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java
@@ -19,15 +19,20 @@
import com.intellij.ide.IdeEventQueue;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
+import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
+import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
import com.intellij.openapi.wm.impl.ToolWindowImpl;
+import com.intellij.ui.GotItMessage;
import com.intellij.ui.IdeBorderFactory;
+import com.intellij.ui.UIBundle;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBList;
@@ -146,16 +151,18 @@
final Dimension size = list.getPreferredSize();
final JComponent c = ToolWindowsWidget.this;
- final RelativePoint point = new RelativePoint(c, new Point(-4, -4 - size.height));
-
+ final Insets padding = UIUtil.getListViewportPadding();
+ final RelativePoint point = new RelativePoint(c, new Point(-4, -padding.top - padding.bottom -4 - size.height));
if (popup != null && popup.isVisible()) {
return;
}
list.setSelectedIndex(list.getItemsCount() - 1);
- popup = JBPopupFactory.getInstance().createListPopupBuilder(list)
+ PopupChooserBuilder builder = JBPopupFactory.getInstance().createListPopupBuilder(list);
+ popup = builder
.setAutoselectOnMouseMove(true)
+ .setRequestFocus(false)
.setItemChoosenCallback(new Runnable() {
@Override
public void run() {
@@ -175,6 +182,26 @@
}
@Override
+ public void addNotify() {
+ super.addNotify();
+ final String key = "toolwindow.stripes.buttons.info.shown";
+ if (UISettings.getInstance().HIDE_TOOL_STRIPES && !PropertiesComponent.getInstance().isTrueValue(key)) {
+ final Alarm alarm = new Alarm();
+ alarm.addRequest(new Runnable() {
+ @Override
+ public void run() {
+ GotItMessage.createMessage(UIBundle.message("tool.window.quick.access.title"), UIBundle.message(
+ "tool.window.quick.access.message"))
+ .setDisposable(ToolWindowsWidget.this)
+ .show(new RelativePoint(ToolWindowsWidget.this, new Point(10, 0)), Balloon.Position.above);
+ PropertiesComponent.getInstance().setValue(key, String.valueOf(true));
+ Disposer.dispose(alarm);
+ }
+ }, 10000);
+ }
+ }
+
+ @Override
public void propertyChange(PropertyChangeEvent evt) {
updateIcon();
}
@@ -262,5 +289,6 @@
Disposer.dispose(this);
KeyboardFocusManager.getCurrentKeyboardFocusManager().removePropertyChangeListener("focusOwner", this);
myStatusBar = null;
+ popup = null;
}
}
diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
index e4f1171..8cc9b3d 100644
--- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
+++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
@@ -159,6 +159,11 @@
if (!myEnabled) hideHint();
}
+ @Override
+ public boolean isEnabled() {
+ return myEnabled;
+ }
+
@NotNull
@Override
public Collection<KeyType> getExpandedItems() {
diff --git a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
index a9eefcb..ce65d0e 100644
--- a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
+++ b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
@@ -15,6 +15,7 @@
*/
package com.intellij.ui;
+import com.intellij.Patches;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
@@ -25,6 +26,7 @@
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.util.PlatformUtils;
@@ -47,6 +49,21 @@
public class AppUIUtil {
private static final String VENDOR_PREFIX = "jetbrains-";
+ public static void patchSystem() {
+ if (Patches.SUN_BUG_ID_9000030 && Registry.is("ide.x11.suppress.xinerama")) {
+ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ if (ge.getScreenDevices().length > 1) {
+ try {
+ @SuppressWarnings("SpellCheckingInspection") Field xinerState = ge.getClass().getDeclaredField("xinerState");
+ xinerState.setAccessible(true);
+ xinerState.set(null, Boolean.FALSE);
+ Logger.getInstance(AppUIUtil.class).info("Xinerama detection suppressed");
+ }
+ catch (Exception ignored) { }
+ }
+ }
+ }
+
public static void updateWindowIcon(@NotNull Window window) {
window.setIconImages(getAppIconImages());
}
diff --git a/platform/platform-impl/src/com/intellij/ui/GotItMessage.java b/platform/platform-impl/src/com/intellij/ui/GotItMessage.java
new file mode 100644
index 0000000..6580d0c
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ui/GotItMessage.java
@@ -0,0 +1,103 @@
+/*
+ * 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.ui;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.ui.popup.Balloon;
+import com.intellij.openapi.ui.popup.BalloonBuilder;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.ui.awt.RelativePoint;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class GotItMessage {
+ @NotNull private final String myTitle;
+ @NotNull private final String myMessage;
+ private Runnable myCallback;
+ private Disposable myDisposable;
+ private boolean myShowCallout = true;
+
+ private GotItMessage(@NotNull String title,
+ @NotNull String message ) {
+ myTitle = title;
+ final String[] lines = message.split("\n");
+ if (lines.length > 1) {
+ myMessage = "<html><div align='center'>" + message.replace("\n", "<br>") + "</div></html>";
+ } else {
+ myMessage = message;
+ }
+ }
+
+ public static GotItMessage createMessage(@NotNull String title,
+ @NotNull String message) {
+ return new GotItMessage(title, message);
+ }
+
+ public GotItMessage setDisposable(Disposable disposable) {
+ myDisposable = disposable;
+ return this;
+ }
+
+ public GotItMessage setCallback(Runnable callback) {
+ myCallback = callback;
+ return this;
+ }
+
+ public GotItMessage setShowCallout(boolean showCallout) {
+ myShowCallout = showCallout;
+ return this;
+ }
+
+ public void show(RelativePoint point, Balloon.Position position) {
+ final GotItPanel panel = new GotItPanel();
+ panel.myTitle.setText(myTitle);
+ panel.myMessage.setText(myMessage);
+
+ panel.myButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ final BalloonBuilder builder = JBPopupFactory.getInstance().createBalloonBuilder(panel.myRoot);
+ if (myDisposable != null) {
+ builder.setDisposable(myDisposable);
+ }
+
+ final Balloon balloon = builder
+ .setFillColor(UIUtil.getListBackground())
+ .setHideOnClickOutside(false)
+ .setHideOnAction(false)
+ .setHideOnFrameResize(false)
+ .setHideOnKeyOutside(false)
+ .setShowCallout(myShowCallout)
+ .createBalloon();
+ panel.myButton.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ balloon.hide();
+ if (myCallback != null) {
+ myCallback.run();
+ }
+ }
+ });
+
+ balloon.show(point, position);
+ }
+
+}
diff --git a/platform/platform-impl/src/com/intellij/ui/GotItPanel.form b/platform/platform-impl/src/com/intellij/ui/GotItPanel.form
new file mode 100644
index 0000000..0fda696
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ui/GotItPanel.form
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ui.GotItPanel">
+ <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="4" left="5" bottom="4" right="5"/>
+ <constraints>
+ <xy x="20" y="20" width="442" height="177"/>
+ </constraints>
+ <properties>
+ <opaque value="false"/>
+ </properties>
+ <border type="none"/>
+ <children>
+ <component id="6805" class="javax.swing.JLabel" binding="myTitle">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <font size="20"/>
+ <text value="Title"/>
+ </properties>
+ </component>
+ <vspacer id="a3eac">
+ <constraints>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </vspacer>
+ <component id="1102e" class="javax.swing.JLabel" binding="myMessage">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <font size="12"/>
+ <text value="Text text text text"/>
+ </properties>
+ </component>
+ <grid id="fd7bc" layout-manager="GridLayoutManager" row-count="1" 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>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <opaque value="false"/>
+ </properties>
+ <border type="none"/>
+ <children>
+ <grid id="50d71" binding="myButton" custom-create="true" layout-manager="BorderLayout" hgap="0" vgap="0">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <background color="-16750951"/>
+ <opaque value="false"/>
+ </properties>
+ <border type="empty">
+ <size top="2" left="10" bottom="2" right="8"/>
+ </border>
+ <children>
+ <component id="366a9" class="javax.swing.JLabel">
+ <constraints border-constraint="Center"/>
+ <properties>
+ <font size="12" style="1"/>
+ <foreground color="-1"/>
+ <text resource-bundle="messages/UIBundle" key="got.it"/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+ <hspacer id="a87ad">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </hspacer>
+ </children>
+ </grid>
+ </children>
+ </grid>
+</form>
diff --git a/platform/platform-impl/src/com/intellij/ui/GotItPanel.java b/platform/platform-impl/src/com/intellij/ui/GotItPanel.java
new file mode 100644
index 0000000..20c43fa
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ui/GotItPanel.java
@@ -0,0 +1,49 @@
+/*
+ * 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.ui;
+
+import com.intellij.util.ui.GraphicsUtil;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+* @author Konstantin Bulenkov
+*/
+public class GotItPanel {
+ JPanel myButton;
+ JPanel myRoot;
+ JLabel myTitle;
+ JLabel myMessage;
+
+ private void createUIComponents() {
+ myButton = new JPanel(new BorderLayout()) {
+ {
+ enableEvents(AWTEvent.MOUSE_EVENT_MASK);
+ }
+ @Override
+ protected void paintComponent(Graphics g) {
+ super.paintComponent(g);
+ GraphicsUtil.setupAAPainting(g);
+ ((Graphics2D)g).setPaint(new GradientPaint(0, 0, new JBColor(new Color(77, 143, 253), new Color(52, 74, 100)), 0, getHeight(),
+ new JBColor(new Color(71, 135, 237), new Color(38, 53, 73))));
+ g.fillRoundRect(0,0,getWidth()-1, getHeight()-1, 5,5);
+ g.setColor(new JBColor(new Color(48, 121, 237), new Color(87, 93, 101)));
+ g.drawRoundRect(0,0,getWidth()-1, getHeight()-1, 5,5);
+ }
+ };
+ }
+}
diff --git a/platform/platform-impl/src/org/jetbrains/ide/BuiltInServerManagerImpl.java b/platform/platform-impl/src/org/jetbrains/ide/BuiltInServerManagerImpl.java
index 006f88b..b783956 100644
--- a/platform/platform-impl/src/org/jetbrains/ide/BuiltInServerManagerImpl.java
+++ b/platform/platform-impl/src/org/jetbrains/ide/BuiltInServerManagerImpl.java
@@ -14,7 +14,7 @@
import com.intellij.openapi.startup.StartupActivity;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.ShutDownTracker;
-import org.jboss.netty.channel.ChannelException;
+import io.netty.channel.ChannelException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -108,7 +108,8 @@
}
try {
- server = new BuiltInServer(workerCount);
+ server = new BuiltInServer();
+ detectedPortNumber = server.start(workerCount, defaultPort, PORTS_COUNT, true);
}
catch (ChannelException e) {
LOG.info(e);
@@ -121,6 +122,13 @@
return;
}
+ if (detectedPortNumber == -1) {
+ LOG.info("built-in server cannot be started, cannot bind to port");
+ return;
+ }
+
+ LOG.info("built-in server started, port " + detectedPortNumber);
+
Disposer.register(ApplicationManager.getApplication(), server);
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
@Override
@@ -131,14 +139,6 @@
}
}
});
-
- detectedPortNumber = server.start(defaultPort, PORTS_COUNT, true);
- if (detectedPortNumber == -1) {
- LOG.info("built-in server cannot be started, cannot bind to port");
- }
- else {
- LOG.info("built-in server started, port " + detectedPortNumber);
- }
}
});
}
diff --git a/platform/platform-impl/src/org/jetbrains/ide/PooledThreadExecutor.java b/platform/platform-impl/src/org/jetbrains/ide/PooledThreadExecutor.java
index 1c24110..952393d 100644
--- a/platform/platform-impl/src/org/jetbrains/ide/PooledThreadExecutor.java
+++ b/platform/platform-impl/src/org/jetbrains/ide/PooledThreadExecutor.java
@@ -5,7 +5,12 @@
import java.util.concurrent.Executor;
-public class PooledThreadExecutor implements Executor {
+public final class PooledThreadExecutor implements Executor {
+ public static final PooledThreadExecutor INSTANCE = new PooledThreadExecutor();
+
+ private PooledThreadExecutor() {
+ }
+
@Override
public void execute(@NotNull Runnable command) {
ApplicationManager.getApplication().executeOnPooledThread(command);
diff --git a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
index 6f61306..85d70892 100644
--- a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
+++ b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
@@ -20,12 +20,12 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.net.NetUtils;
-import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.*;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.channel.group.DefaultChannelGroup;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
-import org.jboss.netty.handler.codec.http.*;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.*;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.handler.codec.http.FullHttpRequest;
+import io.netty.handler.codec.http.HttpMethod;
+import io.netty.handler.codec.http.QueryStringDecoder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.ide.CustomPortServerManager;
@@ -35,73 +35,62 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Map;
-import java.util.concurrent.Executor;
public class BuiltInServer implements Disposable {
- private final ChannelGroup openChannels = new DefaultChannelGroup();
+ private final ChannelRegistrar channelRegistrar = new ChannelRegistrar();
static final Logger LOG = Logger.getInstance(BuiltInServer.class);
- private final NioServerSocketChannelFactory channelFactory;
-
- public BuiltInServer() {
- this(1);
- }
-
- public BuiltInServer(int workerCount) {
- Executor pooledThreadExecutor = new PooledThreadExecutor();
- channelFactory = new NioServerSocketChannelFactory(pooledThreadExecutor, pooledThreadExecutor, workerCount);
- }
-
public boolean isRunning() {
- return !openChannels.isEmpty();
+ return !channelRegistrar.isEmpty();
}
public void start(int port) {
- start(port, 1, false);
+ start(1, port, 1, false);
}
- public int start(int firstPort, int portsCount, boolean tryAnyPort) {
+ public int start(int workerCount, int firstPort, int portsCount, boolean tryAnyPort) {
if (isRunning()) {
throw new IllegalStateException("server already started");
}
- ServerBootstrap bootstrap = createServerBootstrap(channelFactory, openChannels, null);
+ NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup(workerCount, PooledThreadExecutor.INSTANCE);
+ ServerBootstrap bootstrap = createServerBootstrap(eventLoopGroup, channelRegistrar, null);
int port = bind(firstPort, portsCount, tryAnyPort, bootstrap);
- bindCustomPorts(firstPort, port);
+ bindCustomPorts(firstPort, port, eventLoopGroup);
return port;
}
- static ServerBootstrap createServerBootstrap(NioServerSocketChannelFactory channelFactory, ChannelGroup openChannels, @Nullable Map<String, Object> xmlRpcHandlers) {
- ServerBootstrap bootstrap = new ServerBootstrap(channelFactory);
- bootstrap.setOption("child.tcpNoDelay", true);
- bootstrap.setOption("child.keepAlive", true);
+ static ServerBootstrap createServerBootstrap(EventLoopGroup eventLoopGroup, final ChannelRegistrar channelRegistrar, @Nullable Map<String, Object> xmlRpcHandlers) {
+ ServerBootstrap bootstrap = NettyUtil.nioServerBootstrap(eventLoopGroup);
if (xmlRpcHandlers == null) {
- final ChannelHandler handler = new PortUnificationServerHandler(openChannels);
- bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
+ final PortUnificationServerHandler portUnificationServerHandler = new PortUnificationServerHandler();
+ bootstrap.childHandler(new ChannelInitializer() {
@Override
- public ChannelPipeline getPipeline() throws Exception {
- return Channels.pipeline(handler);
+ protected void initChannel(Channel channel) throws Exception {
+ channel.pipeline().addLast(channelRegistrar, portUnificationServerHandler);
}
});
}
else {
final XmlRpcDelegatingHttpRequestHandler handler = new XmlRpcDelegatingHttpRequestHandler(xmlRpcHandlers);
- bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
+ bootstrap.childHandler(new ChannelInitializer() {
@Override
- public ChannelPipeline getPipeline() throws Exception {
- return Channels.pipeline(new HttpRequestDecoder(), new HttpChunkAggregator(1048576), new HttpResponseEncoder(), handler);
+ protected void initChannel(Channel channel) throws Exception {
+ channel.pipeline().addLast(channelRegistrar);
+ NettyUtil.initHttpHandlers(channel.pipeline());
+ channel.pipeline().addLast(handler);
}
});
}
return bootstrap;
}
- private void bindCustomPorts(int firstPort, int port) {
+ private void bindCustomPorts(int firstPort, int port, NioEventLoopGroup eventLoopGroup) {
for (CustomPortServerManager customPortServerManager : CustomPortServerManager.EP_NAME.getExtensions()) {
try {
int customPortServerManagerPort = customPortServerManager.getPort();
- SubServer subServer = new SubServer(customPortServerManager, channelFactory);
+ SubServer subServer = new SubServer(customPortServerManager, eventLoopGroup);
Disposer.register(this, subServer);
if (customPortServerManagerPort != firstPort && customPortServerManagerPort != port) {
subServer.bind(customPortServerManagerPort);
@@ -117,55 +106,40 @@
InetAddress loopbackAddress = NetUtils.getLoopbackAddress();
for (int i = 0; i < portsCount; i++) {
int port = firstPort + i;
- try {
- openChannels.add(bootstrap.bind(new InetSocketAddress(loopbackAddress, port)));
+ ChannelFuture future = bootstrap.bind(loopbackAddress, port).awaitUninterruptibly();
+ if (future.isSuccess()) {
+ channelRegistrar.add(future.channel());
return port;
}
- catch (ChannelException e) {
- if (!openChannels.isEmpty()) {
- openChannels.close();
- openChannels.clear();
- }
-
- if (portsCount == 1) {
- throw e;
- }
- else if (!tryAnyPort && i == (portsCount - 1)) {
- LOG.error(e);
- }
+ else if (!tryAnyPort && i == (portsCount - 1)) {
+ LOG.error(future.cause());
+ return -1;
}
}
- if (tryAnyPort) {
- LOG.info("We cannot bind to our default range, so, try to bind to any free port");
- try {
- Channel channel = bootstrap.bind(new InetSocketAddress(loopbackAddress, 0));
- openChannels.add(channel);
- return ((InetSocketAddress)channel.getLocalAddress()).getPort();
- }
- catch (ChannelException e) {
- LOG.error(e);
- }
+ LOG.info("We cannot bind to our default range, so, try to bind to any free port");
+ ChannelFuture future = bootstrap.bind(loopbackAddress, 0).awaitUninterruptibly();
+ if (future.isSuccess()) {
+ channelRegistrar.add(future.channel());
+ return ((InetSocketAddress)future.channel().localAddress()).getPort();
}
-
- return -1;
+ else {
+ LOG.error(future.cause());
+ return -1;
+ }
}
@Override
public void dispose() {
- try {
- openChannels.close().awaitUninterruptibly();
- }
- finally {
- channelFactory.releaseExternalResources();
- }
+ channelRegistrar.close();
LOG.info("web server stopped");
}
- public static void replaceDefaultHandler(@NotNull ChannelHandlerContext context, @NotNull SimpleChannelUpstreamHandler messageChannelHandler) {
- context.getPipeline().replace(DelegatingHttpRequestHandler.class, "replacedDefaultHandler", messageChannelHandler);
+ public static void replaceDefaultHandler(@NotNull ChannelHandlerContext context, @NotNull SimpleChannelInboundHandler messageChannelHandler) {
+ context.pipeline().replace(DelegatingHttpRequestHandler.class, "replacedDefaultHandler", messageChannelHandler);
}
+ @ChannelHandler.Sharable
private static final class XmlRpcDelegatingHttpRequestHandler extends DelegatingHttpRequestHandlerBase {
private final Map<String, Object> handlers;
@@ -174,9 +148,9 @@
}
@Override
- protected boolean process(ChannelHandlerContext context, HttpRequest request, QueryStringDecoder urlDecoder) throws IOException {
+ protected boolean process(ChannelHandlerContext context, FullHttpRequest request, QueryStringDecoder urlDecoder) throws IOException {
return (request.getMethod() == HttpMethod.POST || request.getMethod() == HttpMethod.OPTIONS) &&
- XmlRpcServer.SERVICE.getInstance().process(urlDecoder.getPath(), request, context, handlers);
+ XmlRpcServer.SERVICE.getInstance().process(urlDecoder.path(), request, context, handlers);
}
}
}
\ No newline at end of file
diff --git a/platform/platform-impl/src/org/jetbrains/io/ChannelExceptionHandler.java b/platform/platform-impl/src/org/jetbrains/io/ChannelExceptionHandler.java
index 2ac00c1..93def2e 100644
--- a/platform/platform-impl/src/org/jetbrains/io/ChannelExceptionHandler.java
+++ b/platform/platform-impl/src/org/jetbrains/io/ChannelExceptionHandler.java
@@ -1,24 +1,33 @@
+/*
+ * 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 org.jetbrains.io;
import com.intellij.openapi.diagnostic.Logger;
-import org.jboss.netty.channel.ChannelEvent;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelUpstreamHandler;
-import org.jboss.netty.channel.ExceptionEvent;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
import java.net.ConnectException;
-public final class ChannelExceptionHandler implements ChannelUpstreamHandler {
+@ChannelHandler.Sharable
+public final class ChannelExceptionHandler extends ChannelInboundHandlerAdapter {
private static final Logger LOG = Logger.getInstance(ChannelExceptionHandler.class);
@Override
- public void handleUpstream(ChannelHandlerContext context, ChannelEvent event) throws Exception {
- if (!(event instanceof ExceptionEvent)) {
- context.sendUpstream(event);
- return;
- }
-
- Throwable cause = ((ExceptionEvent)event).getCause();
+ public void exceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
// don't report about errors while connecting
// WEB-7727
if (!(cause instanceof ConnectException) && !"Connection reset".equals(cause.getMessage())) {
diff --git a/platform/platform-impl/src/org/jetbrains/io/ChannelRegistrar.java b/platform/platform-impl/src/org/jetbrains/io/ChannelRegistrar.java
new file mode 100644
index 0000000..96bb850d
--- /dev/null
+++ b/platform/platform-impl/src/org/jetbrains/io/ChannelRegistrar.java
@@ -0,0 +1,54 @@
+package org.jetbrains.io;
+
+import io.netty.channel.*;
+import io.netty.channel.group.ChannelGroup;
+import io.netty.channel.group.DefaultChannelGroup;
+import io.netty.util.concurrent.ImmediateEventExecutor;
+import org.jetbrains.annotations.NotNull;
+
+@ChannelHandler.Sharable
+public final class ChannelRegistrar extends ChannelInboundHandlerAdapter {
+ private final ChannelGroup openChannels = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE);
+
+ public boolean isEmpty() {
+ return openChannels.isEmpty();
+ }
+
+ public void add(@NotNull Channel serverChannel) {
+ assert serverChannel instanceof ServerChannel;
+ openChannels.add(serverChannel);
+ }
+
+ @Override
+ public void channelActive(ChannelHandlerContext context) throws Exception {
+ // we don't need to remove channel on close - ChannelGroup do it
+ openChannels.add(context.channel());
+
+ super.channelActive(context);
+ }
+
+ public void close() {
+ close(true);
+ }
+
+ public void close(boolean shutdownEventLoopGroup) {
+ EventLoopGroup eventLoopGroup = null;
+ if (shutdownEventLoopGroup) {
+ for (Channel channel : openChannels) {
+ if (channel instanceof ServerChannel) {
+ eventLoopGroup = channel.eventLoop().parent();
+ break;
+ }
+ }
+ }
+
+ try {
+ openChannels.close().awaitUninterruptibly();
+ }
+ finally {
+ if (eventLoopGroup != null) {
+ eventLoopGroup.shutdownGracefully();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/platform/platform-impl/src/org/jetbrains/io/Decoder.java b/platform/platform-impl/src/org/jetbrains/io/Decoder.java
index 45464e5..30052bd 100644
--- a/platform/platform-impl/src/org/jetbrains/io/Decoder.java
+++ b/platform/platform-impl/src/org/jetbrains/io/Decoder.java
@@ -15,24 +15,28 @@
*/
package org.jetbrains.io;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
import org.jetbrains.annotations.Nullable;
-public abstract class Decoder extends SimpleChannelUpstreamHandler {
- protected ChannelBuffer cumulation;
+public abstract class Decoder<I> extends SimpleChannelInboundHandler<I> {
+ protected ByteBuf cumulation;
+
+ protected Decoder() {
+ super(false);
+ }
@Nullable
- protected final ChannelBuffer getBufferIfSufficient(ChannelBuffer input, int requiredLength, ChannelHandlerContext context) {
- if (!input.readable()) {
+ protected final ByteBuf getBufferIfSufficient(ByteBuf input, int requiredLength, ChannelHandlerContext context) {
+ if (!input.isReadable()) {
return null;
}
if (cumulation == null) {
if (input.readableBytes() < requiredLength) {
- cumulation = context.getChannel().getConfig().getBufferFactory().getBuffer(requiredLength);
+ cumulation = context.channel().config().getAllocator().buffer(requiredLength);
cumulation.writeBytes(input);
return null;
}
@@ -46,7 +50,7 @@
return null;
}
else {
- ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(cumulation, input);
+ ByteBuf buffer = Unpooled.wrappedBuffer(cumulation, input);
input.skipBytes(input.readableBytes());
cumulation = null;
return buffer;
diff --git a/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandler.java b/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandler.java
index e2464d3..e7809ac 100644
--- a/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandler.java
+++ b/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandler.java
@@ -18,13 +18,17 @@
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.util.IconLoader;
import com.intellij.util.ui.UIUtil;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.http.FullHttpRequest;
+import io.netty.handler.codec.http.HttpResponse;
+import io.netty.handler.codec.http.QueryStringDecoder;
+import io.netty.util.Attribute;
+import io.netty.util.AttributeKey;
import org.apache.sanselan.ImageFormat;
import org.apache.sanselan.ImageWriteException;
import org.apache.sanselan.Sanselan;
-import org.jboss.netty.channel.ChannelHandler;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.handler.codec.http.HttpRequest;
-import org.jboss.netty.handler.codec.http.QueryStringDecoder;
import org.jetbrains.ide.BuiltInServerManager;
import org.jetbrains.ide.HttpRequestHandler;
@@ -34,23 +38,24 @@
@ChannelHandler.Sharable
final class DelegatingHttpRequestHandler extends DelegatingHttpRequestHandlerBase {
+ private static final AttributeKey<HttpRequestHandler> PREV_HANDLER = new AttributeKey<HttpRequestHandler>("DelegatingHttpRequestHandler.handler");
+
@Override
- protected boolean process(ChannelHandlerContext context, HttpRequest request, QueryStringDecoder urlDecoder) throws IOException, ImageWriteException {
- HttpRequestHandler connectedHandler = (HttpRequestHandler)context.getAttachment();
+ protected boolean process(ChannelHandlerContext context, FullHttpRequest request, QueryStringDecoder urlDecoder) throws IOException, ImageWriteException {
+ Attribute<HttpRequestHandler> prevHandlerAttribute = context.attr(PREV_HANDLER);
+ HttpRequestHandler connectedHandler = prevHandlerAttribute.get();
if (connectedHandler != null) {
if (connectedHandler.isSupported(request) && connectedHandler.process(urlDecoder, request, context)) {
return true;
}
// prev cached connectedHandler is not suitable for this request, so, let's find it again
- context.setAttachment(null);
+ prevHandlerAttribute.set(null);
}
for (HttpRequestHandler handler : BuiltInServerManager.EP_NAME.getExtensions()) {
try {
if (handler.isSupported(request) && handler.process(urlDecoder, request, context)) {
- if (context.getAttachment() == null) {
- context.setAttachment(handler);
- }
+ prevHandlerAttribute.set(handler);
return true;
}
}
@@ -59,17 +64,26 @@
}
}
- if (urlDecoder.getPath().equals("/favicon.ico")) {
+ if (urlDecoder.path().equals("/favicon.ico")) {
Icon icon = IconLoader.findIcon(ApplicationInfoEx.getInstanceEx().getSmallIconUrl());
if (icon != null) {
BufferedImage image = UIUtil.createImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
icon.paintIcon(null, image.getGraphics(), 0, 0);
byte[] icoBytes = Sanselan.writeImageToBytes(image, ImageFormat.IMAGE_FORMAT_ICO, null);
- Responses.send(icoBytes, FileResponses.createResponse(urlDecoder.getPath()), request, context);
+ HttpResponse response = Responses.response(FileResponses.getContentType(urlDecoder.path()), Unpooled.wrappedBuffer(icoBytes));
+ Responses.addNoCache(response);
+ Responses.send(response, context.channel(), request);
return true;
}
}
return false;
}
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
+ super.exceptionCaught(context, cause);
+
+ context.attr(PREV_HANDLER).remove();
+ }
}
\ No newline at end of file
diff --git a/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandlerBase.java b/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandlerBase.java
index 7fd497b..2a8f6ea 100644
--- a/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandlerBase.java
+++ b/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandlerBase.java
@@ -15,43 +15,33 @@
*/
package org.jetbrains.io;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ExceptionEvent;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
-import org.jboss.netty.handler.codec.http.HttpRequest;
-import org.jboss.netty.handler.codec.http.QueryStringDecoder;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.handler.codec.http.FullHttpRequest;
+import io.netty.handler.codec.http.HttpResponseStatus;
+import io.netty.handler.codec.http.QueryStringDecoder;
-import static org.jboss.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND;
-
-abstract class DelegatingHttpRequestHandlerBase extends SimpleChannelUpstreamHandler {
+abstract class DelegatingHttpRequestHandlerBase extends SimpleChannelInboundHandler<FullHttpRequest> {
@Override
- public final void messageReceived(ChannelHandlerContext context, MessageEvent event) throws Exception {
- if (!(event.getMessage() instanceof HttpRequest)) {
- context.sendUpstream(event);
- return;
+ protected void channelRead0(ChannelHandlerContext context, FullHttpRequest message) throws Exception {
+ if (BuiltInServer.LOG.isDebugEnabled()) {
+ BuiltInServer.LOG.debug("IN HTTP:\n" + message);
}
- HttpRequest request = (HttpRequest)event.getMessage();
- //if (BuiltInServer.LOG.isDebugEnabled()) {
- //BuiltInServer.LOG.debug(request.toString());
- //}
-
- if (!process(context, request, new QueryStringDecoder(request.getUri()))) {
- Responses.sendStatus(request, context.getChannel(), NOT_FOUND);
+ if (!process(context, message, new QueryStringDecoder(message.getUri()))) {
+ Responses.sendStatus(HttpResponseStatus.NOT_FOUND, context.channel(), message);
}
}
- protected abstract boolean process(ChannelHandlerContext context, HttpRequest request, QueryStringDecoder urlDecoder) throws Exception;
+ protected abstract boolean process(ChannelHandlerContext context, FullHttpRequest request, QueryStringDecoder urlDecoder) throws Exception;
@Override
- public final void exceptionCaught(ChannelHandlerContext context, ExceptionEvent event) throws Exception {
+ public void exceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
try {
- NettyUtil.log(event.getCause(), BuiltInServer.LOG);
+ NettyUtil.log(cause, BuiltInServer.LOG);
}
finally {
- context.setAttachment(null);
- event.getChannel().close();
+ context.channel().close();
}
}
}
\ No newline at end of file
diff --git a/platform/platform-impl/src/org/jetbrains/io/FileResponses.java b/platform/platform-impl/src/org/jetbrains/io/FileResponses.java
index ce70e37..14897fd 100644
--- a/platform/platform-impl/src/org/jetbrains/io/FileResponses.java
+++ b/platform/platform-impl/src/org/jetbrains/io/FileResponses.java
@@ -15,47 +15,39 @@
*/
package org.jetbrains.io;
-import org.jboss.netty.channel.*;
-import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
-import org.jboss.netty.handler.codec.http.HttpMethod;
-import org.jboss.netty.handler.codec.http.HttpRequest;
-import org.jboss.netty.handler.codec.http.HttpResponse;
-import org.jboss.netty.handler.ssl.SslHandler;
-import org.jboss.netty.handler.stream.ChunkedFile;
+import com.intellij.openapi.util.text.StringUtil;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.DefaultFileRegion;
+import io.netty.handler.codec.http.*;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.handler.stream.ChunkedFile;
import javax.activation.MimetypesFileTypeMap;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.ParseException;
import java.util.Date;
-import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
-import static org.jboss.netty.handler.codec.http.HttpHeaders.setContentLength;
-import static org.jboss.netty.handler.codec.http.HttpResponseStatus.NOT_MODIFIED;
-import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
+import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
import static org.jetbrains.io.Responses.*;
public class FileResponses {
private static final MimetypesFileTypeMap FILE_MIMETYPE_MAP = new MimetypesFileTypeMap();
- public static HttpResponse createResponse(String path) {
- HttpResponse response = create(FILE_MIMETYPE_MAP.getContentType(path));
- response.setHeader(CACHE_CONTROL, "no-cache, no-store, must-revalidate, max-age=0");
- response.setHeader(PRAGMA, "no-cache");
- return response;
+ public static String getContentType(String path) {
+ return FILE_MIMETYPE_MAP.getContentType(path);
}
private static boolean checkCache(HttpRequest request, Channel channel, long lastModified) {
- String ifModifiedSince = request.getHeader(IF_MODIFIED_SINCE);
- if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) {
+ String ifModifiedSince = request.headers().get(HttpHeaders.Names.IF_MODIFIED_SINCE);
+ if (!StringUtil.isEmpty(ifModifiedSince)) {
try {
if (Responses.DATE_FORMAT.get().parse(ifModifiedSince).getTime() >= lastModified) {
- HttpResponse response = new DefaultHttpResponse(HTTP_1_1, NOT_MODIFIED);
- addAllowAnyOrigin(response);
- addDate(response);
- addServer(response);
- send(response, channel, request);
+ send(response(HttpResponseStatus.NOT_MODIFIED), channel, request);
return true;
}
}
@@ -72,42 +64,41 @@
return;
}
+ HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
+ response.headers().add(CONTENT_TYPE, getContentType(file.getPath()));
+ addCommonHeaders(response);
+ response.headers().set(HttpHeaders.Names.CACHE_CONTROL, "private, must-revalidate");
+ response.headers().set(HttpHeaders.Names.LAST_MODIFIED, Responses.DATE_FORMAT.get().format(new Date(file.lastModified())));
+
+ boolean keepAlive = addKeepAliveIfNeed(response, request);
+
boolean fileWillBeClosed = false;
- RandomAccessFile raf = new RandomAccessFile(file, "r");
+ RandomAccessFile raf;
+ try {
+ raf = new RandomAccessFile(file, "r");
+ }
+ catch (FileNotFoundException ignored) {
+ send(response(HttpResponseStatus.NOT_FOUND), channel, request);
+ return;
+ }
+
try {
long fileLength = raf.length();
- HttpResponse response = createResponse(file.getPath());
- addCommonHeaders(response);
- response.setHeader(LAST_MODIFIED, Responses.DATE_FORMAT.get().format(new Date(file.lastModified())));
- boolean keepAlive = addKeepAliveIfNeed(response, request);
if (request.getMethod() != HttpMethod.HEAD) {
- setContentLength(response, fileLength);
+ HttpHeaders.setContentLength(response, fileLength);
}
- ChannelFuture future = channel.write(response);
-
+ channel.write(response);
if (request.getMethod() != HttpMethod.HEAD) {
- if (channel.getPipeline().get(SslHandler.class) == null) {
- // No encryption - use zero-copy.
- final FileRegion region = new DefaultFileRegion(raf.getChannel(), 0, fileLength);
- future = channel.write(region);
- future.addListener(new ChannelFutureListener() {
- @Override
- public void operationComplete(ChannelFuture future) {
- region.releaseExternalResources();
- }
- });
+ if (channel.pipeline().get(SslHandler.class) == null) {
+ // no encryption - use zero-copy
+ channel.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength));
}
else {
- // Cannot use zero-copy with HTTPS.
- future = channel.write(new ChunkedFile(raf, 0, fileLength, 8192));
+ // cannot use zero-copy with HTTPS
+ channel.write(new ChunkedFile(raf));
}
}
-
- if (!keepAlive) {
- future.addListener(ChannelFutureListener.CLOSE);
- }
-
fileWillBeClosed = true;
}
finally {
@@ -115,5 +106,10 @@
raf.close();
}
}
+
+ ChannelFuture future = channel.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
+ if (!keepAlive) {
+ future.addListener(ChannelFutureListener.CLOSE);
+ }
}
-}
+}
\ No newline at end of file
diff --git a/platform/platform-impl/src/org/jetbrains/io/NettyUtil.java b/platform/platform-impl/src/org/jetbrains/io/NettyUtil.java
index 293a22b..86ae505 100644
--- a/platform/platform-impl/src/org/jetbrains/io/NettyUtil.java
+++ b/platform/platform-impl/src/org/jetbrains/io/NettyUtil.java
@@ -17,12 +17,17 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.ActionCallback;
-import org.jboss.netty.bootstrap.ClientBootstrap;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelException;
-import org.jboss.netty.channel.ChannelFactory;
-import org.jboss.netty.channel.ChannelFuture;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.*;
+import io.netty.channel.oio.OioEventLoopGroup;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.channel.socket.oio.OioSocketChannel;
+import io.netty.handler.codec.http.HttpObjectAggregator;
+import io.netty.handler.codec.http.HttpRequestDecoder;
+import io.netty.handler.codec.http.HttpResponseEncoder;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.ide.PooledThreadExecutor;
import java.io.IOException;
import java.net.SocketAddress;
@@ -40,18 +45,18 @@
}
}
- public static Channel connectClient(ClientBootstrap bootstrap, SocketAddress remoteAddress, ActionCallback asyncResult) {
+ public static Channel connectClient(Bootstrap bootstrap, SocketAddress remoteAddress, ActionCallback asyncResult) {
return connect(bootstrap, remoteAddress, asyncResult, DEFAULT_CONNECT_ATTEMPT_COUNT);
}
@Nullable
- public static Channel connect(ClientBootstrap bootstrap, SocketAddress remoteAddress, ActionCallback asyncResult, int maxAttemptCount) {
+ public static Channel connect(Bootstrap bootstrap, SocketAddress remoteAddress, ActionCallback asyncResult, int maxAttemptCount) {
int attemptCount = 0;
while (true) {
try {
ChannelFuture future = bootstrap.connect(remoteAddress).await();
if (future.isSuccess()) {
- return future.getChannel();
+ return future.channel();
}
else if (asyncResult.isRejected()) {
return null;
@@ -84,13 +89,29 @@
// applicable only in case of ClientBootstrap&OioClientSocketChannelFactory
public static void closeAndReleaseFactory(Channel channel) {
- ChannelFactory channelFactory = channel.getFactory();
+ EventLoop channelFactory = channel.eventLoop();
try {
channel.close().awaitUninterruptibly();
}
finally {
// in our case it does nothing, we don't use ExecutorService, but we are aware of future changes
- channelFactory.releaseExternalResources();
+ channelFactory.shutdownGracefully();
}
}
+
+ public static ServerBootstrap nioServerBootstrap(EventLoopGroup eventLoopGroup) {
+ ServerBootstrap bootstrap = new ServerBootstrap().group(eventLoopGroup).channel(NioServerSocketChannel.class);
+ bootstrap.childOption(ChannelOption.TCP_NODELAY, true).childOption(ChannelOption.SO_KEEPALIVE, true);
+ return bootstrap;
+ }
+
+ public static Bootstrap oioClientBootstrap() {
+ Bootstrap bootstrap = new Bootstrap().group(new OioEventLoopGroup(1, PooledThreadExecutor.INSTANCE)).channel(OioSocketChannel.class);
+ bootstrap.option(ChannelOption.TCP_NODELAY, true).option(ChannelOption.SO_KEEPALIVE, true);
+ return bootstrap;
+ }
+
+ public static void initHttpHandlers(ChannelPipeline pipeline) {
+ pipeline.addLast(new HttpRequestDecoder(), new HttpObjectAggregator(1048576), new HttpResponseEncoder());
+ }
}
\ No newline at end of file
diff --git a/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java b/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java
index 1662ab0..1169763 100644
--- a/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java
+++ b/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java
@@ -16,30 +16,24 @@
package org.jetbrains.io;
import com.intellij.openapi.util.AtomicNotNullLazyValue;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.*;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.handler.codec.compression.ZlibDecoder;
-import org.jboss.netty.handler.codec.compression.ZlibEncoder;
-import org.jboss.netty.handler.codec.compression.ZlibWrapper;
-import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
-import org.jboss.netty.handler.codec.http.HttpContentCompressor;
-import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
-import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
-import org.jboss.netty.handler.ssl.SslHandler;
-import org.jboss.netty.handler.stream.ChunkedWriteHandler;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.*;
+import io.netty.handler.codec.compression.JZlibEncoder;
+import io.netty.handler.codec.compression.JdkZlibDecoder;
+import io.netty.handler.codec.compression.ZlibWrapper;
+import io.netty.handler.codec.http.HttpMessage;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.handler.stream.ChunkedWriteHandler;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
-import java.net.SocketAddress;
import java.security.KeyStore;
import java.security.Security;
@ChannelHandler.Sharable
-final class PortUnificationServerHandler extends Decoder {
+final class PortUnificationServerHandler extends Decoder<ByteBuf> {
private static final AtomicNotNullLazyValue<SSLContext> SSL_SERVER_CONTEXT = new AtomicNotNullLazyValue<SSLContext>() {
@NotNull
@Override
@@ -69,73 +63,67 @@
private final boolean detectSsl;
private final boolean detectGzip;
- private final ChannelGroup openChannels;
private final DelegatingHttpRequestHandler delegatingHttpRequestHandler;
- public PortUnificationServerHandler(ChannelGroup openChannels) {
- this(new DelegatingHttpRequestHandler(), openChannels, true, true);
+ public PortUnificationServerHandler() {
+ this(new DelegatingHttpRequestHandler(), true, true);
}
- private PortUnificationServerHandler(DelegatingHttpRequestHandler delegatingHttpRequestHandler, @Nullable ChannelGroup openChannels, boolean detectSsl, boolean detectGzip) {
+ private PortUnificationServerHandler(DelegatingHttpRequestHandler delegatingHttpRequestHandler, boolean detectSsl, boolean detectGzip) {
this.delegatingHttpRequestHandler = delegatingHttpRequestHandler;
- this.openChannels = openChannels;
this.detectSsl = detectSsl;
this.detectGzip = detectGzip;
}
@Override
- public void channelOpen(ChannelHandlerContext context, ChannelStateEvent e) {
- if (openChannels != null) {
- openChannels.add(e.getChannel());
+ protected void channelRead0(ChannelHandlerContext context, ByteBuf message) throws Exception {
+ ByteBuf buffer = getBufferIfSufficient(message, 5, context);
+ if (buffer == null) {
+ message.release();
+ }
+ else {
+ decode(context, buffer);
}
}
- @Override
- public void messageReceived(ChannelHandlerContext context, MessageEvent e) throws Exception {
- Object m = e.getMessage();
- if (!(m instanceof ChannelBuffer)) {
- context.sendUpstream(e);
- return;
- }
-
- ChannelBuffer buffer = getBufferIfSufficient((ChannelBuffer)m, 5, context);
- if (buffer != null) {
- decode(context, buffer, e.getRemoteAddress());
- }
- }
-
- private void decode(ChannelHandlerContext context, ChannelBuffer buffer, SocketAddress remoteAddress) throws Exception {
- ChannelPipeline pipeline = context.getPipeline();
+ private void decode(ChannelHandlerContext context, ByteBuf buffer) throws Exception {
+ ChannelPipeline pipeline = context.pipeline();
if (detectSsl && SslHandler.isEncrypted(buffer)) {
SSLEngine engine = SSL_SERVER_CONTEXT.getValue().createSSLEngine();
engine.setUseClientMode(false);
- pipeline.addLast("ssl", new SslHandler(engine));
- pipeline.addLast("streamer", new ChunkedWriteHandler());
- pipeline.addLast("unificationWOSsl", new PortUnificationServerHandler(delegatingHttpRequestHandler, null, false, detectGzip));
+ pipeline.addLast(new SslHandler(engine), new ChunkedWriteHandler());
+ pipeline.addLast(new PortUnificationServerHandler(delegatingHttpRequestHandler, false, detectGzip));
}
else {
int magic1 = buffer.getUnsignedByte(buffer.readerIndex());
int magic2 = buffer.getUnsignedByte(buffer.readerIndex() + 1);
if (detectGzip && magic1 == 31 && magic2 == 139) {
- pipeline.addLast("gzipDeflater", new ZlibEncoder(ZlibWrapper.GZIP));
- pipeline.addLast("gzipInflater", new ZlibDecoder(ZlibWrapper.GZIP));
- pipeline.addLast("unificationWOGzip", new PortUnificationServerHandler(delegatingHttpRequestHandler, null, detectSsl, false));
+ pipeline.addLast(new JZlibEncoder(ZlibWrapper.GZIP), new JdkZlibDecoder(ZlibWrapper.GZIP));
+ pipeline.addLast(new PortUnificationServerHandler(delegatingHttpRequestHandler, detectSsl, false));
}
else {
- pipeline.addLast("decoder", new HttpRequestDecoder());
- pipeline.addLast("aggregator", new HttpChunkAggregator(1048576));
- pipeline.addLast("encoder", new HttpResponseEncoder());
- pipeline.addLast("deflater", new HttpContentCompressor());
- pipeline.addLast("handler", delegatingHttpRequestHandler);
+ NettyUtil.initHttpHandlers(pipeline);
+ pipeline.addLast(delegatingHttpRequestHandler);
+ if (BuiltInServer.LOG.isDebugEnabled()) {
+ pipeline.addLast(new ChannelOutboundHandlerAdapter() {
+ @Override
+ public void write(ChannelHandlerContext context, Object message, ChannelPromise promise) throws Exception {
+ if (message instanceof HttpMessage) {
+ BuiltInServer.LOG.debug("OUT HTTP:\n" + message);
+ }
+ super.write(context, message, promise);
+ }
+ });
+ }
}
}
// must be after new channels handlers addition (netty bug?)
pipeline.remove(this);
- Channels.fireMessageReceived(context, buffer, remoteAddress);
+ context.fireChannelRead(buffer);
}
@Override
- public void exceptionCaught(ChannelHandlerContext context, ExceptionEvent event) throws Exception {
- NettyUtil.log(event.getCause(), BuiltInServer.LOG);
+ public void exceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
+ NettyUtil.log(cause, BuiltInServer.LOG);
}
}
\ No newline at end of file
diff --git a/platform/platform-impl/src/org/jetbrains/io/Responses.java b/platform/platform-impl/src/org/jetbrains/io/Responses.java
index 55f603a..fbe7d86 100644
--- a/platform/platform-impl/src/org/jetbrains/io/Responses.java
+++ b/platform/platform-impl/src/org/jetbrains/io/Responses.java
@@ -19,14 +19,14 @@
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.util.text.StringUtil;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFuture;
-import org.jboss.netty.channel.ChannelFutureListener;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.handler.codec.http.*;
-import org.jboss.netty.util.CharsetUtil;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.http.*;
+import io.netty.util.CharsetUtil;
import org.jetbrains.annotations.Nullable;
import java.nio.charset.Charset;
@@ -37,11 +37,7 @@
import java.util.Locale;
import java.util.TimeZone;
-import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
-import static org.jboss.netty.handler.codec.http.HttpHeaders.isKeepAlive;
-import static org.jboss.netty.handler.codec.http.HttpHeaders.setContentLength;
-import static org.jboss.netty.handler.codec.http.HttpResponseStatus.OK;
-import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
+import static io.netty.handler.codec.http.HttpHeaders.Names.*;
public final class Responses {
static final ThreadLocal<DateFormat> DATE_FORMAT = new ThreadLocal<DateFormat>() {
@@ -56,16 +52,36 @@
private static String SERVER_HEADER_VALUE;
+ public static FullHttpResponse response(HttpResponseStatus status) {
+ return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, Unpooled.EMPTY_BUFFER);
+ }
+
+ public static HttpResponse response(@Nullable String contentType, @Nullable ByteBuf content) {
+ HttpResponse response =
+ new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content == null ? Unpooled.EMPTY_BUFFER : content);
+ if (contentType != null) {
+ response.headers().add(CONTENT_TYPE, contentType);
+ }
+ return response;
+ }
+
public static void addAllowAnyOrigin(HttpResponse response) {
- response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
+ response.headers().add(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
}
public static void addDate(HttpResponse response) {
- addDate(response, Calendar.getInstance().getTime());
+ if (!response.headers().contains(DATE)) {
+ addDate(response, Calendar.getInstance().getTime());
+ }
}
public static void addDate(HttpResponse response, Date date) {
- response.setHeader(DATE, DATE_FORMAT.get().format(date));
+ response.headers().set(DATE, DATE_FORMAT.get().format(date));
+ }
+
+ public static void addNoCache(HttpResponse response) {
+ response.headers().add(CACHE_CONTROL, "no-cache, no-store, must-revalidate, max-age=0");
+ response.headers().add(PRAGMA, "no-cache");
}
@Nullable
@@ -81,32 +97,23 @@
public static void addServer(HttpResponse response) {
if (getServerHeaderValue() != null) {
- response.setHeader(SERVER, getServerHeaderValue());
+ response.headers().add(SERVER, getServerHeaderValue());
}
}
- public static void send(String contentType, CharSequence content, HttpRequest request, ChannelHandlerContext context) {
- HttpResponse response = create(contentType);
- response.setContent(ChannelBuffers.copiedBuffer(content, CharsetUtil.UTF_8));
- send(response, request, context);
- }
-
- public static void send(HttpResponse response, @Nullable HttpRequest request, ChannelHandlerContext context) {
- send(response, context.getChannel(), request);
- }
-
public static void send(HttpResponse response, Channel channel, @Nullable HttpRequest request) {
- ChannelBuffer content = response.getContent();
- setContentLength(response, content == ChannelBuffers.EMPTY_BUFFER ? 0 : content.readableBytes());
+ if (response.getStatus() != HttpResponseStatus.NOT_MODIFIED && !HttpHeaders.isContentLengthSet(response)) {
+ HttpHeaders.setContentLength(response,
+ response instanceof FullHttpResponse ? ((FullHttpResponse)response).content().readableBytes() : 0);
+ }
- boolean keepAlive = request != null && addKeepAliveIfNeed(response, request);
addCommonHeaders(response);
- send(response, channel, !keepAlive);
+ send(response, channel, request != null && !addKeepAliveIfNeed(response, request));
}
public static boolean addKeepAliveIfNeed(HttpResponse response, HttpRequest request) {
- if (isKeepAlive(request)) {
- response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
+ if (HttpHeaders.isKeepAlive(request)) {
+ HttpHeaders.setKeepAlive(response, true);
return true;
}
return false;
@@ -118,84 +125,63 @@
addAllowAnyOrigin(response);
}
- public static HttpResponse create(String contentType) {
- HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
- response.setHeader(CONTENT_TYPE, contentType);
- return response;
+ public static void send(CharSequence content, Channel channel, @Nullable HttpRequest request) {
+ send(content, CharsetUtil.US_ASCII, channel, request);
}
- public static void send(CharSequence content, HttpRequest request, ChannelHandlerContext context) {
- send(content, CharsetUtil.US_ASCII, request, context);
- }
-
- public static void send(CharSequence content, Charset charset, HttpRequest request, ChannelHandlerContext context) {
- DefaultHttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
- response.setContent(ChannelBuffers.copiedBuffer(content, charset));
- send(response, request, context);
- }
-
- public static void send(byte[] bytes, HttpResponse response, HttpRequest request, ChannelHandlerContext context) {
- response.setContent(ChannelBuffers.wrappedBuffer(bytes));
- send(response, request, context);
- }
-
- public static void send(HttpResponse response, ChannelHandlerContext context) {
- send(response, context.getChannel(), true);
- }
-
- public static void send(HttpResponseStatus status, ChannelHandlerContext context) {
- send(new DefaultHttpResponse(HTTP_1_1, status), context);
+ public static void send(CharSequence content, Charset charset, Channel channel, @Nullable HttpRequest request) {
+ send(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.copiedBuffer(content, charset)), channel, request);
}
private static void send(HttpResponse response, Channel channel, boolean close) {
- if (!channel.isOpen()) {
+ if (!channel.isActive()) {
return;
}
ChannelFuture future = channel.write(response);
+ if (!(response instanceof FullHttpResponse)) {
+ channel.write(LastHttpContent.EMPTY_LAST_CONTENT);
+ }
+ channel.flush();
if (close) {
future.addListener(ChannelFutureListener.CLOSE);
}
}
- public static void sendStatus(HttpRequest request, Channel channel, HttpResponseStatus responseStatus, @Nullable String description) {
- sendStatus(new DefaultHttpResponse(HTTP_1_1, responseStatus), request, channel, description);
- }
-
- public static void sendStatus(HttpRequest request, Channel channel, HttpResponseStatus responseStatus) {
- sendStatus(request, channel, responseStatus, null);
- }
-
- public static void sendStatus(HttpResponse response, HttpRequest request, Channel channel) {
- sendStatus(response, request, channel, null);
- }
-
public static void sendStatus(HttpResponseStatus responseStatus, Channel channel) {
- sendStatus(new DefaultHttpResponse(HTTP_1_1, responseStatus), null, channel, null);
+ sendStatus(responseStatus, channel, null);
}
- private static void sendStatus(HttpResponse response, @Nullable HttpRequest request, Channel channel, @Nullable String description) {
- response.setHeader(CONTENT_TYPE, "text/html");
- if (request == null || request.getMethod() != HttpMethod.HEAD) {
- String message = response.getStatus().toString();
+ public static void sendStatus(HttpResponseStatus responseStatus, Channel channel, @Nullable HttpRequest request) {
+ sendStatus(responseStatus, channel, null, request);
+ }
- StringBuilder builder = new StringBuilder();
- builder.append("<!doctype html><title>").append(message).append("</title>").append("<h1 style=\"text-align: center\">").append(message).append("</h1>");
- if (description != null) {
- builder.append("<p>").append(description).append("</p>");
- }
- builder.append("<hr/><p style=\"text-align: center\">").append(StringUtil.notNullize(getServerHeaderValue(), "")).append("</p>");
+ public static void sendStatus(HttpResponseStatus responseStatus, Channel channel, @Nullable String description, @Nullable HttpRequest request) {
+ send(createStatusResponse(responseStatus, request, description), channel, request);
+ }
- response.setContent(ChannelBuffers.copiedBuffer(builder, CharsetUtil.UTF_8));
+ private static HttpResponse createStatusResponse(HttpResponseStatus responseStatus, @Nullable HttpRequest request, @Nullable String description) {
+ if (request != null && request.getMethod() == HttpMethod.HEAD) {
+ return response(responseStatus);
}
- send(response, channel, request);
+
+ StringBuilder builder = new StringBuilder();
+ String message = responseStatus.toString();
+ builder.append("<!doctype html><title>").append(message).append("</title>").append("<h1 style=\"text-align: center\">").append(message).append("</h1>");
+ if (description != null) {
+ builder.append("<p>").append(description).append("</p>");
+ }
+ builder.append("<hr/><p style=\"text-align: center\">").append(StringUtil.notNullize(getServerHeaderValue(), "")).append("</p>");
+
+ DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, responseStatus, Unpooled.copiedBuffer(builder, CharsetUtil.UTF_8));
+ response.headers().set(CONTENT_TYPE, "text/html");
+ return response;
}
public static void sendOptionsResponse(String allowHeaders, HttpRequest request, ChannelHandlerContext context) {
- HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
- response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
- response.setHeader(ACCESS_CONTROL_ALLOW_METHODS, allowHeaders);
- response.setHeader(ALLOW, allowHeaders);
- send(response, request, context);
+ HttpResponse response = response(HttpResponseStatus.OK);
+ response.headers().set(ACCESS_CONTROL_ALLOW_METHODS, allowHeaders);
+ response.headers().set(ALLOW, allowHeaders);
+ send(response, context.channel(), request);
}
}
\ No newline at end of file
diff --git a/platform/platform-impl/src/org/jetbrains/io/SubServer.java b/platform/platform-impl/src/org/jetbrains/io/SubServer.java
index 12512be..ee070e7 100644
--- a/platform/platform-impl/src/org/jetbrains/io/SubServer.java
+++ b/platform/platform-impl/src/org/jetbrains/io/SubServer.java
@@ -17,24 +17,23 @@
import com.intellij.openapi.Disposable;
import com.intellij.util.net.NetUtils;
-import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.channel.group.DefaultChannelGroup;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.EventLoopGroup;
import org.jetbrains.ide.BuiltInServerManager;
import org.jetbrains.ide.CustomPortServerManager;
import java.net.InetSocketAddress;
final class SubServer implements CustomPortServerManager.CustomPortService, Disposable {
- private final ChannelGroup openChannels = new DefaultChannelGroup();
+ private final ChannelRegistrar channelRegistrar = new ChannelRegistrar();
+
private final CustomPortServerManager user;
private final ServerBootstrap bootstrap;
- public SubServer(CustomPortServerManager user, NioServerSocketChannelFactory channelFactory) {
+ public SubServer(CustomPortServerManager user, EventLoopGroup eventLoopGroup) {
this.user = user;
user.setManager(this);
- bootstrap = BuiltInServer.createServerBootstrap(channelFactory, openChannels, user.createXmlRpcHandlers());
+ bootstrap = BuiltInServer.createServerBootstrap(eventLoopGroup, channelRegistrar, user.createXmlRpcHandlers());
}
public boolean bind(int port) {
@@ -43,7 +42,8 @@
}
try {
- openChannels.add(bootstrap.bind(user.isAvailableExternally() ? new InetSocketAddress(port) : new InetSocketAddress(NetUtils.getLoopbackAddress(), port)));
+ bootstrap.localAddress(user.isAvailableExternally() ? new InetSocketAddress(port) : new InetSocketAddress(NetUtils.getLoopbackAddress(), port));
+ channelRegistrar.add(bootstrap.bind().syncUninterruptibly().channel());
return true;
}
catch (Exception e) {
@@ -55,12 +55,11 @@
@Override
public boolean isBound() {
- return !openChannels.isEmpty();
+ return !channelRegistrar.isEmpty();
}
private void stop() {
- openChannels.close().awaitUninterruptibly();
- openChannels.clear();
+ channelRegistrar.close(false);
}
@Override
diff --git a/platform/platform-resources-en/src/messages/RefactoringBundle.properties b/platform/platform-resources-en/src/messages/RefactoringBundle.properties
index 1ef645f..7f9d09d 100644
--- a/platform/platform-resources-en/src/messages/RefactoringBundle.properties
+++ b/platform/platform-resources-en/src/messages/RefactoringBundle.properties
@@ -644,7 +644,7 @@
replace.this.code.fragment.and.change.signature=\nMethod signature will be changed to \n{0}
process.duplicates.title=Process Duplicate {0} of {1}
process.methods.duplicates.title=Process Method {2} Duplicate ({0} of {1})
-0.has.detected.1.code.fragments.in.this.file.that.can.be.replaced.with.a.call.to.extracted.method={0} has detected {1} code fragments in this file that can be replaced with a call to extracted method. Would you like to review and replace them?
+0.has.detected.1.code.fragments.in.this.file.that.can.be.replaced.with.a.call.to.extracted.method={0} has detected {1} code {1,choice,1#fragment|2#fragments} in this file that can be replaced with a call to extracted method. Would you like to review and replace {1,choice,1#it|2#them}?
replace.button=Replace
method.duplicates.method.label=Method {0}
usages.detected.title=Usages Detected
diff --git a/platform/platform-resources-en/src/messages/UIBundle.properties b/platform/platform-resources-en/src/messages/UIBundle.properties
index 04a5c32..b1dc189 100644
--- a/platform/platform-resources-en/src/messages/UIBundle.properties
+++ b/platform/platform-resources-en/src/messages/UIBundle.properties
@@ -158,3 +158,8 @@
message.nothingToShow=Nothing to show
message.noMatchesFound=No matches found
+
+tool.window.quick.access.title=Tool Windows Quick Access
+tool.window.quick.access.message=Hover over the icon below to access tool windows\nTo restore the old layout simply click the icon
+
+got.it=Got it!
diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties
index 8769198..0676fe2 100644
--- a/platform/platform-resources-en/src/misc/registry.properties
+++ b/platform/platform-resources-en/src/misc/registry.properties
@@ -64,7 +64,8 @@
# suppress inspection "UnusedProperty"
idea.fix.mac.env.description=On Mac, use shell environment for external processes (effective on restart).
-idea.x11.skip.wm.patching=false
+ide.x11.override.wm=true
+ide.x11.suppress.xinerama=true
ide.appIcon.progress=true
ide.appIcon.badge=true
@@ -230,7 +231,7 @@
ide.goto.middle.matching=true
# suppress inspection "UnusedProperty"
ide.goto.middle.matching.description=Suggest items in goto actions that contain the entered string somewhere in the middle.
-ide.goto.rebuild.delay=300
+ide.goto.rebuild.delay=0
ide.enable.toolwindow.stack=false
@@ -310,4 +311,7 @@
windows.jumplist=false
windows.jumplist.description=Enables JumpLists on Windows
-external.system.in.process=false
\ No newline at end of file
+# suppress inspection "UnusedProperty"
+GRADLE.system.in.process=true
+# suppress inspection "UnusedProperty"
+GRADLE.system.in.process.description=Whether IDEA should use 'in-process' mode for interaction with gradle api
\ No newline at end of file
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
index a7227be..8c05bb9 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
@@ -257,6 +257,7 @@
<statistics.usagesCollector implementation="com.intellij.internal.statistic.UsageTrigger$MyCollector"/>
<!--<statistics.usagesCollector implementation="com.intellij.internal.statistic.ideSettings.IdeSettingsUsagesCollector"/>-->
<statistics.usagesCollector implementation="com.intellij.internal.statistic.ideSettings.LaFUsagesCollector"/>
+ <statistics.usagesCollector implementation="com.intellij.internal.statistic.OsInfoUsageCollector"/>
<applicationConfigurable instance="com.intellij.internal.statistic.configurable.StatisticsConfigurable" id="usage.statistics"
displayName="Usage Statistics"/>
diff --git a/platform/remote-servers/api/remote-servers-api.iml b/platform/remote-servers/api/remote-servers-api.iml
index deb49db..c9b160c 100644
--- a/platform/remote-servers/api/remote-servers-api.iml
+++ b/platform/remote-servers/api/remote-servers-api.iml
@@ -8,8 +8,8 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="core-api" />
- <orderEntry type="module" module-name="platform-api" />
<orderEntry type="module" module-name="compiler-openapi" />
+ <orderEntry type="module" module-name="lang-api" />
</component>
</module>
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java b/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java
index 3f4bebc..f599d7c 100644
--- a/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java
@@ -7,7 +7,9 @@
import com.intellij.remoteServer.configuration.deployment.DeploymentConfigurator;
import com.intellij.remoteServer.runtime.ServerConnector;
import com.intellij.remoteServer.runtime.ServerTaskExecutor;
+import com.intellij.remoteServer.runtime.deployment.debug.DebugConnector;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -43,4 +45,12 @@
@NotNull
public abstract ServerConnector<?> createConnector(@NotNull C configuration, @NotNull ServerTaskExecutor asyncTasksExecutor);
+
+ /**
+ * @return a non-null instance of {@link DebugConnector} if the server supports deployment in debug mode
+ */
+ @Nullable
+ public DebugConnector<?,?> createDebugConnector() {
+ return null;
+ }
}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/DeploymentTask.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/DeploymentTask.java
index b77df4f..e126f34 100644
--- a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/DeploymentTask.java
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/DeploymentTask.java
@@ -21,4 +21,6 @@
@NotNull
LoggingHandler getLoggingHandler();
+
+ boolean isDebugMode();
}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebugConnectionData.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebugConnectionData.java
new file mode 100644
index 0000000..73c1820
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebugConnectionData.java
@@ -0,0 +1,7 @@
+package com.intellij.remoteServer.runtime.deployment.debug;
+
+/**
+ * @author nik
+ */
+public interface DebugConnectionData {
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebugConnectionDataNotAvailableException.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebugConnectionDataNotAvailableException.java
new file mode 100644
index 0000000..840eaf5
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebugConnectionDataNotAvailableException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.remoteServer.runtime.deployment.debug;
+
+/**
+ * @author nik
+ */
+public class DebugConnectionDataNotAvailableException extends Exception {
+ public DebugConnectionDataNotAvailableException(String message) {
+ super(message);
+ }
+
+ public DebugConnectionDataNotAvailableException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebugConnector.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebugConnector.java
new file mode 100644
index 0000000..d707452
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebugConnector.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.remoteServer.runtime.deployment.debug;
+
+import com.intellij.remoteServer.runtime.deployment.DeploymentRuntime;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Implement this class if a server supports deployment in debug mode. When an user starts a deployment run configuration using 'Debug' button
+ * the following happens:
+ * <ul>
+ * <li>deployment process is started as usual by calling {@link com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance#deploy deploy}
+ * method; you can check whether deployment is started in debug mode or not by using {@link com.intellij.remoteServer.runtime.deployment.DeploymentTask#isDebugMode() task.isDebugMode()} method</li>
+ * <li>when deployment is finished successfully {@link #getConnectionData} method
+ * is called to retrieve information necessary for debugger from the deployed instance</li>
+ * <li>{@link DebuggerLauncher} is used to start debugging</li>
+ * </ul>
+ *
+ * @author nik
+ * @see com.intellij.remoteServer.ServerType#createDebugConnector()
+ * @see com.intellij.remoteServer.runtime.deployment.DeploymentTask#isDebugMode()
+ */
+public abstract class DebugConnector<D extends DebugConnectionData, R extends DeploymentRuntime> {
+ /**
+ * @see com.intellij.remoteServer.runtime.deployment.debug.JavaDebuggerLauncher#getInstance()
+ */
+ @NotNull
+ public abstract DebuggerLauncher<D> getLauncher();
+
+ @NotNull
+ public abstract D getConnectionData(@NotNull R runtime) throws DebugConnectionDataNotAvailableException;
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebuggerLauncher.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebuggerLauncher.java
new file mode 100644
index 0000000..6901fe8
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/DebuggerLauncher.java
@@ -0,0 +1,13 @@
+package com.intellij.remoteServer.runtime.deployment.debug;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.remoteServer.configuration.RemoteServer;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public interface DebuggerLauncher<D extends DebugConnectionData> {
+ void startDebugSession(@NotNull D info, @NotNull ExecutionEnvironment executionEnvironment, RemoteServer<?> server) throws ExecutionException;
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/JavaDebugConnectionData.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/JavaDebugConnectionData.java
new file mode 100644
index 0000000..e5d63a8
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/JavaDebugConnectionData.java
@@ -0,0 +1,25 @@
+package com.intellij.remoteServer.runtime.deployment.debug;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class JavaDebugConnectionData implements DebugConnectionData {
+ private final String myHost;
+ private final int myPort;
+
+ public JavaDebugConnectionData(@NotNull String host, int port) {
+ myHost = host;
+ myPort = port;
+ }
+
+ @NotNull
+ public String getHost() {
+ return myHost;
+ }
+
+ public int getPort() {
+ return myPort;
+ }
+}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/JavaDebuggerLauncher.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/JavaDebuggerLauncher.java
new file mode 100644
index 0000000..ad459ae
--- /dev/null
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/debug/JavaDebuggerLauncher.java
@@ -0,0 +1,12 @@
+package com.intellij.remoteServer.runtime.deployment.debug;
+
+import com.intellij.openapi.components.ServiceManager;
+
+/**
+ * @author nik
+ */
+public abstract class JavaDebuggerLauncher implements DebuggerLauncher<JavaDebugConnectionData> {
+ public static JavaDebuggerLauncher getInstance() {
+ return ServiceManager.getService(JavaDebuggerLauncher.class);
+ }
+}
diff --git a/platform/remote-servers/impl/remote-servers-impl.iml b/platform/remote-servers/impl/remote-servers-impl.iml
index 51c6c6f8..737907a 100644
--- a/platform/remote-servers/impl/remote-servers-impl.iml
+++ b/platform/remote-servers/impl/remote-servers-impl.iml
@@ -13,6 +13,8 @@
<orderEntry type="module" module-name="lang-api" />
<orderEntry type="module" module-name="compiler-openapi" />
<orderEntry type="module" module-name="lang-impl" />
+ <orderEntry type="module" module-name="compiler-impl" />
+ <orderEntry type="module" module-name="xdebugger-api" />
</component>
</module>
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerConfigurationType.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerConfigurationType.java
index c7e406e..527c33a 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerConfigurationType.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerConfigurationType.java
@@ -19,9 +19,12 @@
import com.intellij.execution.configurations.ConfigurationTypeBase;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.impl.run.BuildArtifactsBeforeRunTaskProvider;
import com.intellij.remoteServer.ServerType;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.configuration.RemoteServersManager;
+import com.intellij.remoteServer.configuration.deployment.ArtifactDeploymentSource;
import com.intellij.remoteServer.configuration.deployment.DeploymentConfigurator;
import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
import com.intellij.util.containers.ContainerUtil;
@@ -33,7 +36,7 @@
* @author nik
*/
public class DeployToServerConfigurationType extends ConfigurationTypeBase {
- private ServerType<?> myServerType;
+ private final ServerType<?> myServerType;
public DeployToServerConfigurationType(ServerType<?> serverType) {
super(serverType.getId() + "-deploy", serverType.getPresentableName() + " Deployment",
@@ -62,6 +65,12 @@
DeploymentSource source = ContainerUtil.getFirstItem(sources);
if (source != null) {
deployConfiguration.setDeploymentSource(source);
+ if (source instanceof ArtifactDeploymentSource) {
+ Artifact artifact = ((ArtifactDeploymentSource)source).getArtifact();
+ if (artifact != null) {
+ BuildArtifactsBeforeRunTaskProvider.setBuildArtifactBeforeRun(configuration.getProject(), configuration, artifact);
+ }
+ }
}
}
}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java
index 235a274..1850988 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java
@@ -67,6 +67,11 @@
myDeploymentConfigurator = deploymentConfigurator;
}
+ @NotNull
+ public ServerType<S> getServerType() {
+ return myServerType;
+ }
+
public String getServerName() {
return myServerName;
}
@@ -79,7 +84,7 @@
@NotNull
@Override
public SettingsEditor<DeployToServerRunConfiguration> getConfigurationEditor() {
- return new DeployToServerSettingsEditor(myServerType, myDeploymentConfigurator);
+ return new DeployToServerSettingsEditor(myServerType, myDeploymentConfigurator, getProject());
}
@Nullable
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerSettingsEditor.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerSettingsEditor.java
index a4190f6..ee18ac1 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerSettingsEditor.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerSettingsEditor.java
@@ -18,13 +18,17 @@
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.options.ShowSettingsUtil;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.impl.run.BuildArtifactsBeforeRunTaskProvider;
import com.intellij.remoteServer.ServerType;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.configuration.RemoteServersManager;
import com.intellij.remoteServer.configuration.ServerConfiguration;
+import com.intellij.remoteServer.configuration.deployment.ArtifactDeploymentSource;
import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration;
import com.intellij.remoteServer.configuration.deployment.DeploymentConfigurator;
import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
@@ -46,6 +50,7 @@
public class DeployToServerSettingsEditor<S extends ServerConfiguration, D extends DeploymentConfiguration> extends SettingsEditor<DeployToServerRunConfiguration<S, D>> {
private final ServerType<S> myServerType;
private final DeploymentConfigurator<D> myDeploymentConfigurator;
+ private final Project myProject;
private final ComboboxWithBrowseButton myServerComboBox;
private final ComboBox mySourceComboBox;
private final SortedComboBoxModel<String> myServerListModel;
@@ -54,9 +59,10 @@
private SettingsEditor<D> myDeploymentSettingsEditor;
private DeploymentSource myLastSelection;
- public DeployToServerSettingsEditor(final ServerType<S> type, DeploymentConfigurator<D> deploymentConfigurator) {
+ public DeployToServerSettingsEditor(final ServerType<S> type, DeploymentConfigurator<D> deploymentConfigurator, Project project) {
myServerType = type;
myDeploymentConfigurator = deploymentConfigurator;
+ myProject = project;
myServerListModel = new SortedComboBoxModel<String>(String.CASE_INSENSITIVE_ORDER);
myServerComboBox = new ComboboxWithBrowseButton(new ComboBox(myServerListModel));
@@ -102,7 +108,7 @@
mySourceComboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- updateDeploymentSettings(null);
+ onDeploymentSourceChanged(null);
}
});
}
@@ -116,7 +122,7 @@
myServerComboBox.getComboBox().setSelectedItem(newSelection != null ? newSelection.getName() : oldSelection);
}
- private void updateDeploymentSettings(@Nullable D configuration) {
+ private void onDeploymentSourceChanged(@Nullable D configuration) {
DeploymentSource selected = mySourceListModel.getSelectedItem();
if (Comparing.equal(selected, myLastSelection)) {
if (configuration != null && myDeploymentSettingsEditor != null) {
@@ -125,6 +131,8 @@
return;
}
+ updateBeforeRunOptions(myLastSelection, false);
+ updateBeforeRunOptions(selected, true);
myDeploymentSettingsComponent.removeAll();
myDeploymentSettingsEditor = myDeploymentConfigurator.createEditor(selected);
if (myDeploymentSettingsEditor != null) {
@@ -137,6 +145,15 @@
myLastSelection = selected;
}
+ private void updateBeforeRunOptions(@Nullable DeploymentSource source, boolean selected) {
+ if (source instanceof ArtifactDeploymentSource) {
+ Artifact artifact = ((ArtifactDeploymentSource)source).getArtifact();
+ if (artifact != null) {
+ BuildArtifactsBeforeRunTaskProvider.setBuildArtifactBeforeRunOption(myServerComboBox, myProject, artifact, selected);
+ }
+ }
+ }
+
@Override
protected void resetEditorFrom(DeployToServerRunConfiguration<S,D> configuration) {
String serverName = configuration.getServerName();
@@ -145,7 +162,7 @@
}
myServerComboBox.getComboBox().setSelectedItem(serverName);
mySourceComboBox.setSelectedItem(configuration.getDeploymentSource());
- updateDeploymentSettings(configuration.getDeploymentConfiguration());
+ onDeploymentSourceChanged(configuration.getDeploymentConfiguration());
}
@Override
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerRunner.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerRunner.java
index e3561b3..d86168b 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerRunner.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerRunner.java
@@ -1,6 +1,7 @@
package com.intellij.remoteServer.impl.runtime;
import com.intellij.execution.configurations.RunProfile;
+import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.runners.DefaultProgramRunner;
import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
@@ -18,6 +19,15 @@
@Override
public boolean canRun(@NotNull String executorId, @NotNull RunProfile profile) {
- return executorId.equals(DefaultRunExecutor.EXECUTOR_ID) && profile instanceof DeployToServerRunConfiguration;
+ if (!(profile instanceof DeployToServerRunConfiguration)) {
+ return false;
+ }
+ if (executorId.equals(DefaultRunExecutor.EXECUTOR_ID)) {
+ return true;
+ }
+ if (executorId.equals(DefaultDebugExecutor.EXECUTOR_ID)) {
+ return ((DeployToServerRunConfiguration<?, ?>)profile).getServerType().createDebugConnector() != null;
+ }
+ return false;
}
}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerState.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerState.java
index 59cf6ad..a8fab93 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerState.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerState.java
@@ -19,6 +19,7 @@
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.RunProfileState;
+import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.openapi.project.Project;
@@ -30,6 +31,7 @@
import com.intellij.remoteServer.impl.runtime.log.LoggingHandlerImpl;
import com.intellij.remoteServer.runtime.ServerConnection;
import com.intellij.remoteServer.runtime.ServerConnectionManager;
+import com.intellij.remoteServer.runtime.deployment.debug.DebugConnector;
import com.intellij.remoteServer.runtime.log.LoggingHandler;
import com.intellij.remoteServer.runtime.ui.RemoteServersView;
import com.intellij.util.ParameterizedRunnable;
@@ -62,7 +64,14 @@
RemoteServersView.getInstance(project).showServerConnection(connection);
LoggingHandler loggingHandler = new LoggingHandlerImpl(project);
- connection.deploy(new DeploymentTaskImpl(mySource, myConfiguration, project, loggingHandler), new ParameterizedRunnable<String>() {
+ DebugConnector<?,?> debugConnector;
+ if (DefaultDebugExecutor.getDebugExecutorInstance().equals(executor)) {
+ debugConnector = myServer.getType().createDebugConnector();
+ }
+ else {
+ debugConnector = null;
+ }
+ connection.deploy(new DeploymentTaskImpl(mySource, myConfiguration, project, loggingHandler, debugConnector, myEnvironment), new ParameterizedRunnable<String>() {
@Override
public void run(String s) {
RemoteServersView.getInstance(project).showDeployment(connection, s);
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionImpl.java
index ea83602..c239b35 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionImpl.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionImpl.java
@@ -1,10 +1,14 @@
package com.intellij.remoteServer.impl.runtime;
+import com.intellij.execution.ExecutionException;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ui.ComponentContainer;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration;
import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
import com.intellij.remoteServer.impl.runtime.deployment.DeploymentImpl;
+import com.intellij.remoteServer.impl.runtime.deployment.DeploymentTaskImpl;
import com.intellij.remoteServer.impl.runtime.log.LoggingHandlerImpl;
import com.intellij.remoteServer.runtime.ConnectionStatus;
import com.intellij.remoteServer.runtime.Deployment;
@@ -14,6 +18,9 @@
import com.intellij.remoteServer.runtime.deployment.DeploymentStatus;
import com.intellij.remoteServer.runtime.deployment.DeploymentTask;
import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance;
+import com.intellij.remoteServer.runtime.deployment.debug.DebugConnectionData;
+import com.intellij.remoteServer.runtime.deployment.debug.DebugConnectionDataNotAvailableException;
+import com.intellij.remoteServer.runtime.deployment.debug.DebugConnector;
import com.intellij.util.ParameterizedRunnable;
import com.intellij.util.containers.ConcurrentHashMap;
import org.jetbrains.annotations.NotNull;
@@ -25,6 +32,7 @@
* @author nik
*/
public class ServerConnectionImpl<D extends DeploymentConfiguration> implements ServerConnection<D> {
+ private static final Logger LOG = Logger.getInstance(ServerConnectionImpl.class);
private final RemoteServer<?> myServer;
private final ServerConnector<D> myConnector;
private final ServerConnectionEventDispatcher myEventDispatcher;
@@ -101,9 +109,11 @@
DeploymentSource source = task.getSource();
String deploymentName = instance.getDeploymentName(source);
myLocalDeployments.put(deploymentName, new DeploymentImpl(deploymentName, DeploymentStatus.DEPLOYING, null, null));
- myLoggingHandlers.put(deploymentName, (LoggingHandlerImpl)task.getLoggingHandler());
+ LoggingHandlerImpl handler = (LoggingHandlerImpl)task.getLoggingHandler();
+ handler.printlnSystemMessage("Deploying '" + deploymentName + "'...");
+ myLoggingHandlers.put(deploymentName, handler);
onDeploymentStarted.run(deploymentName);
- instance.deploy(task, new DeploymentOperationCallbackImpl(deploymentName));
+ instance.deploy(task, new DeploymentOperationCallbackImpl(deploymentName, (DeploymentTaskImpl<D>)task, handler));
}
});
}
@@ -159,15 +169,20 @@
final String deploymentName = deployment.getName();
myLocalDeployments.put(deploymentName, new DeploymentImpl(deploymentName, DeploymentStatus.UNDEPLOYING, null, null));
myEventDispatcher.queueDeploymentsChanged(this);
+ final LoggingHandlerImpl loggingHandler = myLoggingHandlers.get(deploymentName);
+ loggingHandler.printlnSystemMessage("Undeploying '" + deploymentName + "'...");
runtime.undeploy(new DeploymentRuntime.UndeploymentTaskCallback() {
@Override
public void succeeded() {
+ loggingHandler.printlnSystemMessage("'" + deploymentName + "' has been undeployed successfully.");
myLocalDeployments.remove(deploymentName);
+ myLoggingHandlers.remove(deploymentName);
myEventDispatcher.queueDeploymentsChanged(ServerConnectionImpl.this);
}
@Override
public void errorOccurred(@NotNull String errorMessage) {
+ loggingHandler.printlnSystemMessage("Failed to undeploy '" + deploymentName + "': " + errorMessage);
myLocalDeployments.put(deploymentName, new DeploymentImpl(deploymentName, DeploymentStatus.DEPLOYED, errorMessage, runtime));
myEventDispatcher.queueDeploymentsChanged(ServerConnectionImpl.this);
}
@@ -228,19 +243,51 @@
private class DeploymentOperationCallbackImpl implements ServerRuntimeInstance.DeploymentOperationCallback {
private final String myDeploymentName;
+ private final DeploymentTaskImpl<D> myDeploymentTask;
+ private final LoggingHandlerImpl myLoggingHandler;
- public DeploymentOperationCallbackImpl(String deploymentName) {
+ public DeploymentOperationCallbackImpl(String deploymentName, DeploymentTaskImpl<D> deploymentTask, LoggingHandlerImpl handler) {
myDeploymentName = deploymentName;
+ myDeploymentTask = deploymentTask;
+ myLoggingHandler = handler;
}
@Override
public void succeeded(@NotNull DeploymentRuntime deployment) {
+ myLoggingHandler.printlnSystemMessage("'" + myDeploymentName + "' has been deployed successfully.");
myLocalDeployments.put(myDeploymentName, new DeploymentImpl(myDeploymentName, DeploymentStatus.DEPLOYED, null, deployment));
myEventDispatcher.queueDeploymentsChanged(ServerConnectionImpl.this);
+ DebugConnector<?,?> debugConnector = myDeploymentTask.getDebugConnector();
+ if (debugConnector != null) {
+ launchDebugger(debugConnector, deployment);
+ }
+ }
+
+ private <D extends DebugConnectionData, R extends DeploymentRuntime> void launchDebugger(@NotNull final DebugConnector<D, R> debugConnector,
+ @NotNull DeploymentRuntime runtime) {
+ try {
+ final D debugInfo = debugConnector.getConnectionData((R)runtime);
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ public void run() {
+ try {
+ debugConnector.getLauncher().startDebugSession(debugInfo, myDeploymentTask.getExecutionEnvironment(), myServer);
+ }
+ catch (ExecutionException e) {
+ myLoggingHandler.print("Cannot start debugger: " + e.getMessage() + "\n");
+ LOG.info(e);
+ }
+ }
+ });
+ }
+ catch (DebugConnectionDataNotAvailableException e) {
+ myLoggingHandler.print("Cannot retrieve debug connection: " + e.getMessage() + "\n");
+ LOG.info(e);
+ }
}
@Override
public void errorOccurred(@NotNull String errorMessage) {
+ myLoggingHandler.printlnSystemMessage("Failed to deploy '" + myDeploymentName + "': " + errorMessage);
myLocalDeployments.put(myDeploymentName, new DeploymentImpl(myDeploymentName, DeploymentStatus.NOT_DEPLOYED, errorMessage, null));
myEventDispatcher.queueDeploymentsChanged(ServerConnectionImpl.this);
}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerTaskExecutorImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerTaskExecutorImpl.java
index 4372296..d9c717f 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerTaskExecutorImpl.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerTaskExecutorImpl.java
@@ -13,11 +13,10 @@
*/
public class ServerTaskExecutorImpl implements ServerTaskExecutor {
private static final Logger LOG = Logger.getInstance(ServerTaskExecutorImpl.class);
- private static final PooledThreadExecutor POOLED_THREAD_EXECUTOR = new PooledThreadExecutor();
private final SequentialTaskExecutor myTaskExecutor;
public ServerTaskExecutorImpl() {
- myTaskExecutor = new SequentialTaskExecutor(POOLED_THREAD_EXECUTOR);
+ myTaskExecutor = new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE);
}
@Override
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentTaskImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentTaskImpl.java
index b8efa2e..3f34d7e 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentTaskImpl.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentTaskImpl.java
@@ -1,11 +1,14 @@
package com.intellij.remoteServer.impl.runtime.deployment;
+import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.project.Project;
import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration;
import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
import com.intellij.remoteServer.runtime.deployment.DeploymentTask;
+import com.intellij.remoteServer.runtime.deployment.debug.DebugConnector;
import com.intellij.remoteServer.runtime.log.LoggingHandler;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author nik
@@ -15,12 +18,17 @@
private final D myConfiguration;
private final Project myProject;
private final LoggingHandler myLoggingHandler;
+ private final DebugConnector<?,?> myDebugConnector;
+ private final ExecutionEnvironment myExecutionEnvironment;
- public DeploymentTaskImpl(DeploymentSource source, D configuration, Project project, LoggingHandler loggingHandler) {
+ public DeploymentTaskImpl(DeploymentSource source, D configuration, Project project, LoggingHandler loggingHandler,
+ DebugConnector<?, ?> connector, ExecutionEnvironment environment) {
mySource = source;
myConfiguration = configuration;
myProject = project;
myLoggingHandler = loggingHandler;
+ myDebugConnector = connector;
+ myExecutionEnvironment = environment;
}
@NotNull
@@ -43,4 +51,19 @@
public Project getProject() {
return myProject;
}
+
+ @Override
+ public boolean isDebugMode() {
+ return myDebugConnector != null;
+ }
+
+ @Nullable
+ public DebugConnector<?, ?> getDebugConnector() {
+ return myDebugConnector;
+ }
+
+ @NotNull
+ public ExecutionEnvironment getExecutionEnvironment() {
+ return myExecutionEnvironment;
+ }
}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/log/LoggingHandlerImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/log/LoggingHandlerImpl.java
index 503cd3c..bd5e010 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/log/LoggingHandlerImpl.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/log/LoggingHandlerImpl.java
@@ -27,6 +27,10 @@
myConsole.print(s, ConsoleViewContentType.NORMAL_OUTPUT);
}
+ public void printlnSystemMessage(@NotNull String s) {
+ myConsole.print(s + "\n", ConsoleViewContentType.SYSTEM_OUTPUT);
+ }
+
@Override
public void attachToProcess(@NotNull ProcessHandler handler) {
myConsole.attachToProcess(handler);
diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
index 8bf0af5..29b0c25 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
@@ -147,18 +147,18 @@
}
URL resource = PlatformTestCase.class.getClassLoader().getResource("idea/ApplicationInfo.xml");
if (resource == null) {
- resource = PlatformTestCase.class.getClassLoader().getResource("idea/IdeaApplicationInfo.xml");
+ resource = PlatformTestCase.class.getClassLoader().getResource("META-INF/UltimateLangXmlPlugin.xml");
if (resource == null) {
- resource = PlatformTestCase.class.getClassLoader().getResource("META-INF/UltimateLangXmlPlugin.xml");
+ resource = PlatformTestCase.class.getClassLoader().getResource("idea/IdeaApplicationInfo.xml");
if (resource == null) {
setPlatformPrefix("PlatformLangXml");
}
else {
- setPlatformPrefix("UltimateLangXml");
+ setPlatformPrefix("Idea");
}
}
else {
- setPlatformPrefix("Idea");
+ setPlatformPrefix("UltimateLangXml");
}
}
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
index 9cfade6..404eff3 100644
--- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
@@ -530,7 +530,7 @@
public static <T> T assertOneElement(T[] ts) {
Assert.assertNotNull(ts);
- Assert.assertEquals(1, ts.length);
+ Assert.assertEquals(Arrays.asList(ts).toString(), 1, ts.length);
return ts[0];
}
diff --git a/platform/testFramework/testFramework.iml b/platform/testFramework/testFramework.iml
index 7985252..91e0821 100644
--- a/platform/testFramework/testFramework.iml
+++ b/platform/testFramework/testFramework.iml
@@ -26,6 +26,7 @@
<orderEntry type="module" module-name="relaxng" exported="" scope="RUNTIME" />
<orderEntry type="module" module-name="images" exported="" scope="RUNTIME" />
<orderEntry type="module" module-name="RegExpSupport" exported="" scope="RUNTIME" />
+ <orderEntry type="module" module-name="remote-servers-impl" scope="RUNTIME" />
</component>
</module>
diff --git a/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java b/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java
index 443f07e..571b19c 100644
--- a/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java
+++ b/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java
@@ -15,6 +15,7 @@
*/
package com.intellij.util.containers;
+import com.intellij.openapi.util.Pair;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
@@ -60,6 +61,15 @@
return map;
}
+ public static <K, V> Map<K,V> newHashMap(Pair<K, V> first, Pair<K, V>[] entries) {
+ Map<K, V> map = newHashMap();
+ map.put(first.getFirst(), first.getSecond());
+ for (Pair<K, V> entry : entries) {
+ map.put(entry.getFirst(), entry.getSecond());
+ }
+ return map;
+ }
+
@NotNull
public static <K extends Comparable, V> TreeMap<K, V> newTreeMap() {
return new TreeMap<K, V>();
diff --git a/platform/util-rt/src/com/intellij/util/io/LimitedInputStream.java b/platform/util-rt/src/com/intellij/util/io/LimitedInputStream.java
index bc0f868..607d0d4 100644
--- a/platform/util-rt/src/com/intellij/util/io/LimitedInputStream.java
+++ b/platform/util-rt/src/com/intellij/util/io/LimitedInputStream.java
@@ -72,6 +72,10 @@
return Math.min(super.available(), myReadLimit - myBytesRead);
}
+ protected int remainingLimit() {
+ return myReadLimit - myBytesRead;
+ }
+
public synchronized void mark(final int readLimit) {
throw new UnsupportedOperationException();
}
diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java
index 4e1754b..0d601b9 100644
--- a/platform/util/src/com/intellij/icons/AllIcons.java
+++ b/platform/util/src/com/intellij/icons/AllIcons.java
@@ -331,6 +331,7 @@
public static final Icon JavaScript = IconLoader.getIcon("/fileTypes/javaScript.png"); // 16x16
public static final Icon Jsp = IconLoader.getIcon("/fileTypes/jsp.png"); // 16x16
public static final Icon Jspx = IconLoader.getIcon("/fileTypes/jspx.png"); // 16x16
+ public static final Icon Manifest = IconLoader.getIcon("/fileTypes/manifest.png"); // 16x16
public static final Icon Properties = IconLoader.getIcon("/fileTypes/properties.png"); // 16x16
public static final Icon Text = IconLoader.getIcon("/fileTypes/text.png"); // 16x16
public static final Icon TypeScript = IconLoader.getIcon("/fileTypes/typeScript.png"); // 16x16
diff --git a/platform/util/src/com/intellij/openapi/diagnostic/DefaultLogger.java b/platform/util/src/com/intellij/openapi/diagnostic/DefaultLogger.java
index c802ffa..57f60f7 100644
--- a/platform/util/src/com/intellij/openapi/diagnostic/DefaultLogger.java
+++ b/platform/util/src/com/intellij/openapi/diagnostic/DefaultLogger.java
@@ -46,7 +46,7 @@
public void error(String message, @Nullable Throwable t, @NotNull String... details) {
System.err.println("ERROR: " + message);
if (t != null) t.printStackTrace();
- if (details != null && details.length > 0) {
+ if (details.length > 0) {
System.out.println("details: ");
for (String detail : details) {
System.out.println(detail);
diff --git a/platform/util/src/com/intellij/openapi/util/Key.java b/platform/util/src/com/intellij/openapi/util/Key.java
index f2b25db..2c3be89 100644
--- a/platform/util/src/com/intellij/openapi/util/Key.java
+++ b/platform/util/src/com/intellij/openapi/util/Key.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 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.
@@ -16,6 +16,7 @@
package com.intellij.openapi.util;
import com.intellij.util.containers.ConcurrentWeakValueIntObjectHashMap;
+import com.intellij.util.containers.StripedLockIntObjectConcurrentHashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,7 +34,7 @@
public class Key<T> {
private static final AtomicInteger ourKeysCounter = new AtomicInteger();
private final int myIndex = ourKeysCounter.getAndIncrement();
- private final String myName; // for debug purposes only
+ private final String myName;
private static final ConcurrentWeakValueIntObjectHashMap<Key> allKeys = new ConcurrentWeakValueIntObjectHashMap<Key>();
public Key(@NotNull @NonNls String name) {
@@ -102,4 +103,15 @@
//noinspection unchecked
return (Key<T>)allKeys.get(index);
}
+
+ @Nullable
+ public static <T> Key<T> findKeyByName(String name) {
+ for (StripedLockIntObjectConcurrentHashMap.IntEntry<Key> key : allKeys.entries()) {
+ if (name.equals(key.getValue().myName)) {
+ //noinspection unchecked
+ return key.getValue();
+ }
+ }
+ return null;
+ }
}
\ No newline at end of file
diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
index cd9192e..a44aec2 100644
--- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
@@ -28,10 +28,7 @@
import com.intellij.util.text.StringFactory;
import gnu.trove.TObjectHashingStrategy;
import org.intellij.lang.annotations.RegExp;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.annotations.TestOnly;
+import org.jetbrains.annotations.*;
import java.io.*;
import java.lang.reflect.Method;
@@ -633,23 +630,23 @@
* Please note that this method is symlink-unfriendly (i.e. result of "/path/to/link/../next" most probably will differ from
* what {@link java.io.File#getCanonicalPath()} will return) - so use with care.
*/
- @Nullable
+ @Contract("null -> null")
public static String toCanonicalPath(@Nullable String path) {
return toCanonicalPath(path, File.separatorChar);
}
- @Nullable
- public static String toCanonicalPath(@Nullable String path, final char separatorChar) {
+ @Contract("null, _ -> null")
+ public static String toCanonicalPath(@Nullable String path, char separatorChar) {
return toCanonicalPath(path, separatorChar, true);
}
- @Nullable
+ @Contract("null -> null")
public static String toCanonicalUriPath(@Nullable String path) {
return toCanonicalPath(path, '/', false);
}
- @Nullable
- private static String toCanonicalPath(@Nullable String path, final char separatorChar, boolean removeLastSlash) {
+ @Contract("null, _, _ -> null")
+ private static String toCanonicalPath(@Nullable String path, char separatorChar, boolean removeLastSlash) {
if (path == null || path.isEmpty()) {
return path;
}
@@ -682,7 +679,7 @@
++dots;
}
else {
- result.append(c);
+ result.append('.');
}
separator = false;
}
diff --git a/platform/util/src/com/intellij/util/containers/ConcurrentHashMap.java b/platform/util/src/com/intellij/util/containers/ConcurrentHashMap.java
index b5cd8b4..19affac 100644
--- a/platform/util/src/com/intellij/util/containers/ConcurrentHashMap.java
+++ b/platform/util/src/com/intellij/util/containers/ConcurrentHashMap.java
@@ -21,6 +21,8 @@
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
@@ -61,7 +63,7 @@
/**
* The default number of concurrency control segments.
- **/
+ */
static final int DEFAULT_SEGMENTS = Math.min(2, Runtime.getRuntime().availableProcessors()); // CHANGED FROM 16
/**
@@ -76,40 +78,41 @@
* unbounded retries if tables undergo continuous modification
* which would make it impossible to obtain an accurate result.
*/
- static final int RETRIES_BEFORE_LOCK = 2;
+ private static final int RETRIES_BEFORE_LOCK = 2;
/* ---------------- Fields -------------- */
/**
* Mask value for indexing into segments. The upper bits of a
* key's hash code are used to choose the segment.
- **/
- final int segmentMask;
+ */
+ private final int segmentMask;
/**
* Shift value for indexing within segments.
- **/
- final int segmentShift;
+ */
+ private final int segmentShift;
/**
* The segments, each of which is a specialized hash table
*/
- final Segment[] segments;
+ private final Segment[] segments;
- transient Set<K> keySet;
- transient Set<Entry<K,V>> entrySet;
- transient Collection<V> values;
+ private transient Set<K> keySet;
+ private transient Set<Entry<K, V>> entrySet;
+ private transient Collection<V> values;
private final TObjectHashingStrategy<K> myHashingStrategy;
/* ---------------- Small Utilities -------------- */
/**
* Returns the segment that should be used for key with given hash
+ *
* @param hash the hash code for the key
* @return the segment
*/
- final Segment<K,V> segmentFor(int hash) {
- return segments[(hash >>> segmentShift) & segmentMask];
+ private Segment<K, V> segmentFor(int hash) {
+ return segments[hash >>> segmentShift & segmentMask];
}
/* ---------------- Inner Classes -------------- */
@@ -117,7 +120,7 @@
/**
* ConcurrentHashMap list entry. Note that this is never exported
* out as a user-visible Map.Entry.
- *
+ * <p/>
* Because the value field is volatile, not final, it is legal wrt
* the Java Memory Model for an unsynchronized reader to see null
* instead of initial value when read via a data race. Although a
@@ -126,13 +129,13 @@
* backup in case a null (pre-initialized) value is ever seen in
* an unsynchronized access method.
*/
- static final class HashEntry<K,V> {
- final K key;
- final int hash;
- volatile V value;
- final HashEntry<K,V> next;
+ private static final class HashEntry<K, V> {
+ private final K key;
+ private final int hash;
+ private volatile V value;
+ private final HashEntry<K, V> next;
- HashEntry(K key, int hash, HashEntry<K,V> next, V value) {
+ private HashEntry(K key, int hash, HashEntry<K, V> next, V value) {
this.key = key;
this.hash = hash;
this.next = next;
@@ -144,8 +147,8 @@
* Segments are specialized versions of hash tables. This
* subclasses from ReentrantLock opportunistically, just to
* simplify some locking and avoid separate construction.
- **/
- static final class Segment<K,V> extends ReentrantLock implements Serializable {
+ */
+ private static final class Segment<K, V> extends ReentrantLock implements Serializable {
/*
* Segments maintain a table of entry lists that are ALWAYS
* kept in a consistent state, so can be read without locking.
@@ -187,8 +190,8 @@
/**
* The number of elements in this segment's region.
- **/
- transient volatile int count;
+ */
+ private transient volatile int count;
/**
* Number of updates that alter the size of the table. This is
@@ -198,31 +201,32 @@
* we might have an inconsistent view of state so (usually)
* must retry.
*/
- transient int modCount;
+ private transient int modCount;
/**
* The table is rehashed when its size exceeds this threshold.
* (The value of this field is always (int)(capacity *
* loadFactor).)
*/
- transient int threshold;
+ private transient int threshold;
/**
* The per-segment table. Declared as a raw type, casted
* to HashEntry<K,V> on each use.
*/
- transient volatile HashEntry[] table;
+ private transient volatile HashEntry[] table;
/**
* The load factor for the hash table. Even though this value
* is same for all segments, it is replicated to avoid needing
* links to outer object.
+ *
* @serial
*/
- final float loadFactor;
+ private final float loadFactor;
private final TObjectHashingStrategy<K> myHashingStrategy;
- Segment(int initialCapacity, float lf, TObjectHashingStrategy<K> hashingStrategy) {
+ private Segment(int initialCapacity, float lf, TObjectHashingStrategy<K> hashingStrategy) {
loadFactor = lf;
myHashingStrategy = hashingStrategy;
setTable(new HashEntry[initialCapacity]);
@@ -231,8 +235,8 @@
/**
* Set table to new HashEntry array.
* Call only while holding lock or in constructor.
- **/
- void setTable(HashEntry[] newTable) {
+ */
+ private void setTable(HashEntry[] newTable) {
threshold = (int)(newTable.length * loadFactor);
table = newTable;
}
@@ -240,9 +244,9 @@
/**
* Return properly casted first entry of bin for given hash
*/
- HashEntry<K,V> getFirst(int hash) {
+ private HashEntry<K, V> getFirst(int hash) {
HashEntry[] tab = table;
- return (HashEntry<K,V>) tab[hash & (tab.length - 1)];
+ return (HashEntry<K, V>)tab[hash & tab.length - 1];
}
/**
@@ -252,25 +256,27 @@
* its table assignment, which is legal under memory model
* but is not known to ever occur.
*/
- V readValueUnderLock(HashEntry<K,V> e) {
+ private V readValueUnderLock(HashEntry<K, V> e) {
lock();
try {
return e.value;
- } finally {
+ }
+ finally {
unlock();
}
}
/* Specialized implementations of map methods */
- V get(K key, int hash) {
+ private V get(K key, int hash) {
if (count != 0) { // read-volatile
- HashEntry<K,V> e = getFirst(hash);
+ HashEntry<K, V> e = getFirst(hash);
while (e != null) {
- if (e.hash == hash && myHashingStrategy.equals(key,e.key)) {
+ if (e.hash == hash && myHashingStrategy.equals(key, e.key)) {
V v = e.value;
- if (v != null)
+ if (v != null) {
return v;
+ }
return readValueUnderLock(e); // recheck
}
e = e.next;
@@ -279,43 +285,47 @@
return null;
}
- boolean containsKey(K key, int hash) {
+ private boolean containsKey(K key, int hash) {
if (count != 0) { // read-volatile
- HashEntry<K,V> e = getFirst(hash);
+ HashEntry<K, V> e = getFirst(hash);
while (e != null) {
- if (e.hash == hash && myHashingStrategy.equals(key,e.key))
+ if (e.hash == hash && myHashingStrategy.equals(key, e.key)) {
return true;
+ }
e = e.next;
}
}
return false;
}
- boolean containsValue(Object value) {
+ private boolean containsValue(Object value) {
if (count != 0) { // read-volatile
HashEntry[] tab = table;
- int len = tab.length;
- for (int i = 0 ; i < len; i++) {
- for (HashEntry<K,V> e = (HashEntry<K,V>)tab[i];
- e != null ;
+ for (HashEntry tabEntry : tab) {
+ for (HashEntry<K, V> e = (HashEntry<K, V>)tabEntry;
+ e != null;
e = e.next) {
V v = e.value;
if (v == null) // recheck
+ {
v = readValueUnderLock(e);
- if (value.equals(v))
+ }
+ if (value.equals(v)) {
return true;
+ }
}
}
}
return false;
}
- boolean replace(K key, int hash, V oldValue, V newValue) {
+ private boolean replace(K key, int hash, V oldValue, V newValue) {
lock();
try {
- HashEntry<K,V> e = getFirst(hash);
- while (e != null && (e.hash != hash || !myHashingStrategy.equals(key,e.key)))
+ HashEntry<K, V> e = getFirst(hash);
+ while (e != null && (e.hash != hash || !myHashingStrategy.equals(key, e.key))) {
e = e.next;
+ }
boolean replaced = false;
if (e != null && oldValue.equals(e.value)) {
@@ -323,17 +333,19 @@
e.value = newValue;
}
return replaced;
- } finally {
+ }
+ finally {
unlock();
}
}
- V replace(K key, int hash, V newValue) {
+ private V replace(K key, int hash, V newValue) {
lock();
try {
- HashEntry<K,V> e = getFirst(hash);
- while (e != null && (e.hash != hash || !myHashingStrategy.equals(key,e.key)))
+ HashEntry<K, V> e = getFirst(hash);
+ while (e != null && (e.hash != hash || !myHashingStrategy.equals(key, e.key))) {
e = e.next;
+ }
V oldValue = null;
if (e != null) {
@@ -341,48 +353,54 @@
e.value = newValue;
}
return oldValue;
- } finally {
+ }
+ finally {
unlock();
}
}
-
- V put(K key, int hash, V value, boolean onlyIfAbsent) {
+ private V put(K key, int hash, V value, boolean onlyIfAbsent) {
lock();
try {
int c = count;
if (c++ > threshold) // ensure capacity
+ {
rehash();
+ }
HashEntry[] tab = table;
- int index = hash & (tab.length - 1);
- HashEntry<K,V> first = (HashEntry<K,V>) tab[index];
- HashEntry<K,V> e = first;
- while (e != null && (e.hash != hash || !myHashingStrategy.equals(key,e.key)))
+ int index = hash & tab.length - 1;
+ HashEntry<K, V> first = (HashEntry<K, V>)tab[index];
+ HashEntry<K, V> e = first;
+ while (e != null && (e.hash != hash || !myHashingStrategy.equals(key, e.key))) {
e = e.next;
+ }
V oldValue;
if (e != null) {
oldValue = e.value;
- if (!onlyIfAbsent)
+ if (!onlyIfAbsent) {
e.value = value;
+ }
}
else {
oldValue = null;
++modCount;
- tab[index] = new HashEntry<K,V>(key, hash, first, value);
+ tab[index] = new HashEntry<K, V>(key, hash, first, value);
count = c; // write-volatile
}
return oldValue;
- } finally {
+ }
+ finally {
unlock();
}
}
- void rehash() {
+ private void rehash() {
HashEntry[] oldTable = table;
int oldCapacity = oldTable.length;
- if (oldCapacity >= MAXIMUM_CAPACITY)
+ if (oldCapacity >= MAXIMUM_CAPACITY) {
return;
+ }
/*
* Reclassify nodes in each list to new Map. Because we are
@@ -401,24 +419,25 @@
HashEntry[] newTable = new HashEntry[oldCapacity << 1];
threshold = (int)(newTable.length * loadFactor);
int sizeMask = newTable.length - 1;
- for (int i = 0; i < oldCapacity ; i++) {
+ for (int i = 0; i < oldCapacity; i++) {
// We need to guarantee that any existing reads of old Map can
// proceed. So we cannot yet null out each bin.
- HashEntry<K,V> e = (HashEntry<K,V>)oldTable[i];
+ HashEntry<K, V> e = (HashEntry<K, V>)oldTable[i];
if (e != null) {
- HashEntry<K,V> next = e.next;
+ HashEntry<K, V> next = e.next;
int idx = e.hash & sizeMask;
// Single node on list
- if (next == null)
+ if (next == null) {
newTable[idx] = e;
+ }
else {
// Reuse trailing consecutive sequence at same slot
- HashEntry<K,V> lastRun = e;
+ HashEntry<K, V> lastRun = e;
int lastIdx = idx;
- for (HashEntry<K,V> last = next;
+ for (HashEntry<K, V> last = next;
last != null;
last = last.next) {
int k = last.hash & sizeMask;
@@ -430,11 +449,11 @@
newTable[lastIdx] = lastRun;
// Clone all remaining nodes
- for (HashEntry<K,V> p = e; p != lastRun; p = p.next) {
+ for (HashEntry<K, V> p = e; p != lastRun; p = p.next) {
int k = p.hash & sizeMask;
- HashEntry<K,V> n = (HashEntry<K,V>)newTable[k];
- newTable[k] = new HashEntry<K,V>(p.key, p.hash,
- n, p.value);
+ HashEntry<K, V> n = (HashEntry<K, V>)newTable[k];
+ newTable[k] = new HashEntry<K, V>(p.key, p.hash,
+ n, p.value);
}
}
}
@@ -445,16 +464,17 @@
/**
* Remove; match on key only if value null, else match both.
*/
- V remove(K key, int hash, Object value) {
+ private V remove(K key, int hash, V value) {
lock();
try {
int c = count - 1;
HashEntry[] tab = table;
- int index = hash & (tab.length - 1);
- HashEntry<K,V> first = (HashEntry<K,V>)tab[index];
- HashEntry<K,V> e = first;
- while (e != null && (e.hash != hash || !myHashingStrategy.equals(key,e.key)))
+ int index = hash & tab.length - 1;
+ HashEntry<K, V> first = (HashEntry<K, V>)tab[index];
+ HashEntry<K, V> e = first;
+ while (e != null && (e.hash != hash || !myHashingStrategy.equals(key, e.key))) {
e = e.next;
+ }
V oldValue = null;
if (e != null) {
@@ -465,94 +485,101 @@
// in list, but all preceding ones need to be
// cloned.
++modCount;
- HashEntry<K,V> newFirst = e.next;
- for (HashEntry<K,V> p = first; p != e; p = p.next)
- newFirst = new HashEntry<K,V>(p.key, p.hash,
- newFirst, p.value);
+ HashEntry<K, V> newFirst = e.next;
+ for (HashEntry<K, V> p = first; p != e; p = p.next) {
+ newFirst = new HashEntry<K, V>(p.key, p.hash, newFirst, p.value);
+ }
tab[index] = newFirst;
count = c; // write-volatile
}
}
return oldValue;
- } finally {
+ }
+ finally {
unlock();
}
}
- void clear() {
+ private void clear() {
if (count != 0) {
lock();
try {
HashEntry[] tab = table;
- for (int i = 0; i < tab.length ; i++)
+ for (int i = 0; i < tab.length; i++) {
tab[i] = null;
+ }
++modCount;
count = 0; // write-volatile
- } finally {
+ }
+ finally {
unlock();
}
}
}
}
-
-
/* ---------------- Public operations -------------- */
public ConcurrentHashMap(TObjectHashingStrategy<K> hashingStrategy) {
- this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS,hashingStrategy);
+ this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS, hashingStrategy);
}
/**
* Creates a new, empty map with the specified initial
* capacity, load factor, and concurrency level.
*
- * @param initialCapacity the initial capacity. The implementation
- * performs internal sizing to accommodate this many elements.
- * @param loadFactor the load factor threshold, used to control resizing.
- * Resizing may be performed when the average number of elements per
- * bin exceeds this threshold.
+ * @param initialCapacity the initial capacity. The implementation
+ * performs internal sizing to accommodate this many elements.
+ * @param loadFactor the load factor threshold, used to control resizing.
+ * Resizing may be performed when the average number of elements per
+ * bin exceeds this threshold.
* @param concurrencyLevel the estimated number of concurrently
- * updating threads. The implementation performs internal sizing
- * to try to accommodate this many threads.
+ * updating threads. The implementation performs internal sizing
+ * to try to accommodate this many threads.
* @throws IllegalArgumentException if the initial capacity is
- * negative or the load factor or concurrencyLevel are
- * nonpositive.
+ * negative or the load factor or concurrencyLevel are
+ * nonpositive.
*/
public ConcurrentHashMap(int initialCapacity,
float loadFactor, int concurrencyLevel) {
- this(initialCapacity,loadFactor, concurrencyLevel,null);
+ this(initialCapacity, loadFactor, concurrencyLevel, null);
}
- public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel, TObjectHashingStrategy<K> hashingStrategy) {
- if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0)
- throw new IllegalArgumentException();
- if (concurrencyLevel > MAX_SEGMENTS)
+ public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel, TObjectHashingStrategy<K> hashingStrategy) {
+ if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0) {
+ throw new IllegalArgumentException();
+ }
+
+ if (concurrencyLevel > MAX_SEGMENTS) {
concurrencyLevel = MAX_SEGMENTS;
+ }
// Find power-of-two sizes best matching arguments
- int sshift = 0;
int ssize = 1;
while (ssize < concurrencyLevel) {
- ++sshift;
ssize <<= 1;
}
- segmentShift = 12; // the middle of the hash is much more random that its HSB. Especially when we use TObjectHashingStrategy.CANONICAl as a hash provider
+ segmentShift =
+ 12; // the middle of the hash is much more random that its HSB. Especially when we use TObjectHashingStrategy.CANONICAl as a hash provider
segmentMask = ssize - 1;
segments = new Segment[ssize];
- if (initialCapacity > MAXIMUM_CAPACITY)
+ if (initialCapacity > MAXIMUM_CAPACITY) {
initialCapacity = MAXIMUM_CAPACITY;
+ }
int c = initialCapacity / ssize;
- if (c * ssize < initialCapacity)
+ if (c * ssize < initialCapacity) {
++c;
+ }
int cap = 1;
- while (cap < c)
+ while (cap < c) {
cap <<= 1;
+ }
hashingStrategy = hashingStrategy == null ? this : hashingStrategy;
- for (int i = 0; i < segments.length; ++i)
- segments[i] = new Segment<K,V>(cap, loadFactor,hashingStrategy);
+ for (int i = 0; i < segments.length; ++i) {
+ segments[i] = new Segment<K, V>(cap, loadFactor, hashingStrategy);
+ }
myHashingStrategy = hashingStrategy;
}
@@ -561,9 +588,9 @@
* capacity, and with default load factor and concurrencyLevel.
*
* @param initialCapacity the initial capacity. The implementation
- * performs internal sizing to accommodate this many elements.
+ * performs internal sizing to accommodate this many elements.
* @throws IllegalArgumentException if the initial capacity of
- * elements is negative.
+ * elements is negative.
*/
public ConcurrentHashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
@@ -582,10 +609,11 @@
* map is created with a capacity of twice the number of mappings in
* the given map or 11 (whichever is greater), and a default load factor
* and concurrencyLevel.
+ *
* @param t the map
*/
public ConcurrentHashMap(Map<? extends K, ? extends V> t) {
- this(Math.max((int) (t.size() / DEFAULT_LOAD_FACTOR) + 1,
+ this(Math.max((int)(t.size() / DEFAULT_LOAD_FACTOR) + 1,
11),
DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
putAll(t);
@@ -607,10 +635,12 @@
int[] mc = new int[segments.length];
int mcsum = 0;
for (int i = 0; i < segments.length; ++i) {
- if (segments[i].count != 0)
+ if (segments[i].count != 0) {
return false;
- else
+ }
+ else {
mcsum += mc[i] = segments[i].modCount;
+ }
}
// If mcsum happens to be zero, then we know we got a snapshot
// before any modifications at all were made. This is
@@ -618,8 +648,9 @@
if (mcsum != 0) {
for (int i = 0; i < segments.length; ++i) {
if (segments[i].count != 0 ||
- mc[i] != segments[i].modCount)
+ mc[i] != segments[i].modCount) {
return false;
+ }
}
}
return true;
@@ -651,8 +682,9 @@
}
}
}
- if (check == sum)
+ if (check == sum) {
break;
+ }
}
if (check != sum) { // Resort to locking all segments
sum = 0;
@@ -667,12 +699,12 @@
/**
* Returns the value to which the specified key is mapped in this table.
*
- * @param key a key in the table.
- * @return the value to which the key is mapped in this table;
- * <tt>null</tt> if the key is not mapped to any value in
- * this table.
- * @throws NullPointerException if the key is
- * <tt>null</tt>.
+ * @param key a key in the table.
+ * @return the value to which the key is mapped in this table;
+ * <tt>null</tt> if the key is not mapped to any value in
+ * this table.
+ * @throws NullPointerException if the key is
+ * <tt>null</tt>.
*/
@Override
public V get(Object key) {
@@ -683,12 +715,12 @@
/**
* Tests if the specified object is a key in this table.
*
- * @param key possible key.
- * @return <tt>true</tt> if and only if the specified object
- * is a key in this table, as determined by the
- * <tt>equals</tt> method; <tt>false</tt> otherwise.
- * @throws NullPointerException if the key is
- * <tt>null</tt>.
+ * @param key possible key.
+ * @return <tt>true</tt> if and only if the specified object
+ * is a key in this table, as determined by the
+ * <tt>equals</tt> method; <tt>false</tt> otherwise.
+ * @throws NullPointerException if the key is
+ * <tt>null</tt>.
*/
@Override
public boolean containsKey(Object key) {
@@ -705,11 +737,10 @@
* @param value value whose presence in this map is to be tested.
* @return <tt>true</tt> if this map maps one or more keys to the
* specified value.
- * @throws NullPointerException if the value is <tt>null</tt>.
+ * @throws NullPointerException if the value is <tt>null</tt>.
*/
@Override
public boolean containsValue(@NotNull Object value) {
-
// See explanation of modCount use above
final Segment[] segments = this.segments;
@@ -722,8 +753,9 @@
for (int i = 0; i < segments.length; ++i) {
int c = segments[i].count;
mcsum += mc[i] = segments[i].modCount;
- if (segments[i].containsValue(value))
+ if (segments[i].containsValue(value)) {
return true;
+ }
}
boolean cleanSweep = true;
if (mcsum != 0) {
@@ -735,23 +767,27 @@
}
}
}
- if (cleanSweep)
+ if (cleanSweep) {
return false;
+ }
}
// Resort to locking all segments
- for (int i = 0; i < segments.length; ++i)
- segments[i].lock();
+ for (Segment segment : segments) {
+ segment.lock();
+ }
boolean found = false;
try {
- for (int i = 0; i < segments.length; ++i) {
- if (segments[i].containsValue(value)) {
+ for (Segment segment : segments) {
+ if (segment.containsValue(value)) {
found = true;
break;
}
}
- } finally {
- for (int i = 0; i < segments.length; ++i)
- segments[i].unlock();
+ }
+ finally {
+ for (Segment segment : segments) {
+ segment.unlock();
+ }
}
return found;
}
@@ -763,13 +799,13 @@
* full compatibility with class {@link java.util.Hashtable},
* which supported this method prior to introduction of the
* Java Collections framework.
-
- * @param value a value to search for.
- * @return <tt>true</tt> if and only if some key maps to the
- * <tt>value</tt> argument in this table as
- * determined by the <tt>equals</tt> method;
- * <tt>false</tt> otherwise.
- * @throws NullPointerException if the value is <tt>null</tt>.
+ *
+ * @param value a value to search for.
+ * @return <tt>true</tt> if and only if some key maps to the
+ * <tt>value</tt> argument in this table as
+ * determined by the <tt>equals</tt> method;
+ * <tt>false</tt> otherwise.
+ * @throws NullPointerException if the value is <tt>null</tt>.
*/
public boolean contains(Object value) {
return containsValue(value);
@@ -779,16 +815,16 @@
* Maps the specified <tt>key</tt> to the specified
* <tt>value</tt> in this table. Neither the key nor the
* value can be <tt>null</tt>.
- *
+ * <p/>
* <p> The value can be retrieved by calling the <tt>get</tt> method
* with a key that is equal to the original key.
*
- * @param key the table key.
- * @param value the value.
- * @return the previous value of the specified key in this table,
- * or <tt>null</tt> if it did not have one.
- * @throws NullPointerException if the key or value is
- * <tt>null</tt>.
+ * @param key the table key.
+ * @param value the value.
+ * @return the previous value of the specified key in this table,
+ * or <tt>null</tt> if it did not have one.
+ * @throws NullPointerException if the key or value is
+ * <tt>null</tt>.
*/
@Override
public V put(K key, @NotNull V value) {
@@ -807,12 +843,13 @@
* return map.get(key);
* </pre>
* Except that the action is performed atomically.
- * @param key key with which the specified value is to be associated.
+ *
+ * @param key key with which the specified value is to be associated.
* @param value value to be associated with the specified key.
* @return previous value associated with specified key, or <tt>null</tt>
- * if there was no mapping for key.
+ * if there was no mapping for key.
* @throws NullPointerException if the specified key or value is
- * <tt>null</tt>.
+ * <tt>null</tt>.
*/
@Override
public V putIfAbsent(@NotNull K key, @NotNull V value) {
@@ -823,15 +860,17 @@
/**
* Copies all of the mappings from the specified map to this one.
- *
+ * <p/>
* These mappings replace any mappings that this map had for any of the
* keys currently in the specified Map.
*
* @param t Mappings to be stored in this map.
*/
@Override
- public void putAll(Map<? extends K, ? extends V> t) {
- for (Iterator<? extends Entry<? extends K, ? extends V>> it = (Iterator<? extends Entry<? extends K, ? extends V>>) t.entrySet().iterator(); it.hasNext(); ) {
+ public void putAll(@NotNull Map<? extends K, ? extends V> t) {
+ for (
+ Iterator<? extends Entry<? extends K, ? extends V>> it = (Iterator<? extends Entry<? extends K, ? extends V>>)t.entrySet().iterator();
+ it.hasNext(); ) {
Entry<? extends K, ? extends V> e = it.next();
put(e.getKey(), e.getValue());
}
@@ -841,11 +880,11 @@
* Removes the key (and its corresponding value) from this
* table. This method does nothing if the key is not in the table.
*
- * @param key the key that needs to be removed.
- * @return the value to which the key had been mapped in this table,
- * or <tt>null</tt> if the key did not have a mapping.
- * @throws NullPointerException if the key is
- * <tt>null</tt>.
+ * @param key the key that needs to be removed.
+ * @return the value to which the key had been mapped in this table,
+ * or <tt>null</tt> if the key did not have a mapping.
+ * @throws NullPointerException if the key is
+ * <tt>null</tt>.
*/
@Override
public V remove(Object key) {
@@ -863,19 +902,20 @@
* } else return false;
* </pre>
* except that the action is performed atomically.
- * @param key key with which the specified value is associated.
+ *
+ * @param key key with which the specified value is associated.
* @param value value associated with the specified key.
* @return true if the value was removed
* @throws NullPointerException if the specified key is
- * <tt>null</tt>.
+ * <tt>null</tt>.
*/
@Override
public boolean remove(@NotNull Object key, Object value) {
int hash = myHashingStrategy.computeHashCode((K)key);
- return remove((K)key, hash, value);
+ return remove((K)key, hash, (V)value);
}
- public boolean remove(@NotNull K key, int hash, Object value) {
+ public boolean remove(@NotNull K key, int hash, V value) {
return segmentFor(hash).remove(key, hash, value) != null;
}
@@ -889,12 +929,13 @@
* } else return false;
* </pre>
* except that the action is performed atomically.
- * @param key key with which the specified value is associated.
+ *
+ * @param key key with which the specified value is associated.
* @param oldValue value expected to be associated with the specified key.
* @param newValue value to be associated with the specified key.
* @return true if the value was replaced
* @throws NullPointerException if the specified key or values are
- * <tt>null</tt>.
+ * <tt>null</tt>.
*/
@Override
public boolean replace(@NotNull K key, @NotNull V oldValue, @NotNull V newValue) {
@@ -911,12 +952,13 @@
* } else return null;
* </pre>
* except that the action is performed atomically.
- * @param key key with which the specified value is associated.
+ *
+ * @param key key with which the specified value is associated.
* @param value value to be associated with the specified key.
* @return previous value associated with specified key, or <tt>null</tt>
- * if there was no mapping for key.
+ * if there was no mapping for key.
* @throws NullPointerException if the specified key or value is
- * <tt>null</tt>.
+ * <tt>null</tt>.
*/
@Override
public V replace(@NotNull K key, @NotNull V value) {
@@ -949,10 +991,11 @@
*
* @return a set view of the keys contained in this map.
*/
+ @NotNull
@Override
public Set<K> keySet() {
Set<K> ks = keySet;
- return (ks != null) ? ks : (keySet = new KeySet());
+ return ks != null ? ks : (keySet = new KeySet());
}
@@ -972,10 +1015,11 @@
*
* @return a collection view of the values contained in this map.
*/
+ @NotNull
@Override
public Collection<V> values() {
Collection<V> vs = values;
- return (vs != null) ? vs : (values = new Values());
+ return vs == null ? (values = new Values()) : vs;
}
@@ -996,18 +1040,19 @@
*
* @return a collection view of the mappings contained in this map.
*/
+ @NotNull
@Override
- public Set<Entry<K,V>> entrySet() {
- Set<Entry<K,V>> es = entrySet;
- return (es != null) ? es : (entrySet = (Set<Entry<K,V>>) (Set) new EntrySet());
+ public Set<Entry<K, V>> entrySet() {
+ Set<Entry<K, V>> es = entrySet;
+ return es != null ? es : (entrySet = (Set<Entry<K, V>>)(Set)new EntrySet());
}
/**
* Returns an enumeration of the keys in this table.
*
- * @return an enumeration of the keys in this table.
- * @see #keySet
+ * @return an enumeration of the keys in this table.
+ * @see #keySet
*/
public Enumeration<K> keys() {
return new KeyIterator();
@@ -1016,8 +1061,8 @@
/**
* Returns an enumeration of the values in this table.
*
- * @return an enumeration of the values in this table.
- * @see #values
+ * @return an enumeration of the values in this table.
+ * @see #values
*/
public Enumeration<V> elements() {
return new ValueIterator();
@@ -1025,36 +1070,40 @@
/* ---------------- Iterator Support -------------- */
- abstract class HashIterator {
- int nextSegmentIndex;
- int nextTableIndex;
- HashEntry[] currentTable;
- HashEntry<K, V> nextEntry;
+ private abstract class HashIterator {
+ private int nextSegmentIndex;
+ private int nextTableIndex;
+ private HashEntry[] currentTable;
+ private HashEntry<K, V> nextEntry;
HashEntry<K, V> lastReturned;
- HashIterator() {
+ private HashIterator() {
nextSegmentIndex = segments.length - 1;
nextTableIndex = -1;
advance();
}
- public boolean hasMoreElements() { return hasNext(); }
+ public boolean hasMoreElements() {
+ return hasNext();
+ }
- final void advance() {
- if (nextEntry != null && (nextEntry = nextEntry.next) != null)
+ private void advance() {
+ if (nextEntry != null && (nextEntry = nextEntry.next) != null) {
return;
+ }
while (nextTableIndex >= 0) {
- if ( (nextEntry = (HashEntry<K,V>)currentTable[nextTableIndex--]) != null)
+ if ((nextEntry = (HashEntry<K, V>)currentTable[nextTableIndex--]) != null) {
return;
+ }
}
while (nextSegmentIndex >= 0) {
- Segment seg = (Segment)segments[nextSegmentIndex--];
+ Segment seg = segments[nextSegmentIndex--];
if (seg.count != 0) {
currentTable = seg.table;
for (int j = currentTable.length - 1; j >= 0; --j) {
- if ( (nextEntry = (HashEntry<K,V>)currentTable[j]) != null) {
+ if ((nextEntry = (HashEntry<K, V>)currentTable[j]) != null) {
nextTableIndex = j - 1;
return;
}
@@ -1063,38 +1112,51 @@
}
}
- public boolean hasNext() { return nextEntry != null; }
+ public boolean hasNext() {
+ return nextEntry != null;
+ }
- HashEntry<K,V> nextEntry() {
- if (nextEntry == null)
+ HashEntry<K, V> nextEntry() {
+ if (nextEntry == null) {
throw new NoSuchElementException();
+ }
lastReturned = nextEntry;
advance();
return lastReturned;
}
public void remove() {
- if (lastReturned == null)
+ if (lastReturned == null) {
throw new IllegalStateException();
+ }
ConcurrentHashMap.this.remove(lastReturned.key);
lastReturned = null;
}
}
- final class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> {
+ private final class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> {
@Override
- public K next() { return super.nextEntry().key; }
+ public K next() {
+ return super.nextEntry().key;
+ }
+
@Override
- public K nextElement() { return super.nextEntry().key; }
+ public K nextElement() {
+ return super.nextEntry().key;
+ }
}
- final class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> {
+ private final class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> {
@Override
- public V next() { return super.nextEntry().value; }
- @Override
- public V nextElement() { return super.nextEntry().value; }
- }
+ public V next() {
+ return super.nextEntry().value;
+ }
+ @Override
+ public V nextElement() {
+ return super.nextEntry().value;
+ }
+ }
/**
@@ -1103,202 +1165,242 @@
* cannot return internal HashEntry objects. Instead, the iterator
* itself acts as a forwarding pseudo-entry.
*/
- final class EntryIterator extends HashIterator implements Entry<K,V>, Iterator<Entry<K,V>> {
+ private final class EntryIterator extends HashIterator implements Entry<K, V>, Iterator<Entry<K, V>> {
@Override
- public Entry<K,V> next() {
+ public Entry<K, V> next() {
nextEntry();
return this;
}
@Override
public K getKey() {
- if (lastReturned == null)
+ if (lastReturned == null) {
throw new IllegalStateException("Entry was removed");
+ }
return lastReturned.key;
}
@Override
public V getValue() {
- if (lastReturned == null)
+ if (lastReturned == null) {
throw new IllegalStateException("Entry was removed");
+ }
return get(lastReturned.key);
}
@Override
public V setValue(V value) {
- if (lastReturned == null)
+ if (lastReturned == null) {
throw new IllegalStateException("Entry was removed");
+ }
return put(lastReturned.key, value);
}
public boolean equals(Object o) {
// If not acting as entry, just use default.
- if (lastReturned == null)
+ if (lastReturned == null) {
return super.equals(o);
- if (!(o instanceof Entry))
+ }
+ if (!(o instanceof Entry)) {
return false;
+ }
Entry e = (Entry)o;
K o1 = getKey();
K o2 = (K)e.getKey();
- return (o1 == null ? o2 == null : myHashingStrategy.equals(o1,o2)) && eq(getValue(), e.getValue());
+ return (o1 == null ? o2 == null : myHashingStrategy.equals(o1, o2)) && eq(getValue(), e.getValue());
}
public int hashCode() {
// If not acting as entry, just use default.
- if (lastReturned == null)
+ if (lastReturned == null) {
return super.hashCode();
+ }
Object k = getKey();
Object v = getValue();
- return ((k == null) ? 0 : k.hashCode()) ^
- ((v == null) ? 0 : v.hashCode());
+ return (k == null ? 0 : k.hashCode()) ^
+ (v == null ? 0 : v.hashCode());
}
public String toString() {
// If not acting as entry, just use default.
- if (lastReturned == null)
+ if (lastReturned == null) {
return super.toString();
- else
+ }
+ else {
return getKey() + "=" + getValue();
+ }
}
- boolean eq(Object o1, Object o2) {
- return (o1 == null ? o2 == null : o1.equals(o2));
+ private boolean eq(Object o1, Object o2) {
+ return o1 == null ? o2 == null : o1.equals(o2);
}
-
}
- final class KeySet extends AbstractSet<K> {
+ private final class KeySet extends AbstractSet<K> {
+ @NotNull
@Override
public Iterator<K> iterator() {
return new KeyIterator();
}
+
@Override
public int size() {
return ConcurrentHashMap.this.size();
}
+
@Override
public boolean contains(Object o) {
return containsKey(o);
}
+
@Override
public boolean remove(Object o) {
return ConcurrentHashMap.this.remove(o) != null;
}
+
@Override
public void clear() {
ConcurrentHashMap.this.clear();
}
+
+ @NotNull
@Override
public Object[] toArray() {
Collection<K> c = new ArrayList<K>();
- for (Iterator<K> i = iterator(); i.hasNext(); )
- c.add(i.next());
+ for (K k : this) {
+ c.add(k);
+ }
return c.toArray();
}
+
+ @NotNull
@Override
- public <T> T[] toArray(T[] a) {
+ public <T> T[] toArray(@NotNull T[] a) {
Collection<K> c = new ArrayList<K>();
- for (Iterator<K> i = iterator(); i.hasNext(); )
- c.add(i.next());
+ for (K k : this) {
+ c.add(k);
+ }
return c.toArray(a);
}
}
- final class Values extends AbstractCollection<V> {
+ private final class Values extends AbstractCollection<V> {
+ @NotNull
@Override
public Iterator<V> iterator() {
return new ValueIterator();
}
+
@Override
public int size() {
return ConcurrentHashMap.this.size();
}
+
@Override
public boolean contains(Object o) {
return containsValue(o);
}
+
@Override
public void clear() {
ConcurrentHashMap.this.clear();
}
+
+ @NotNull
@Override
public Object[] toArray() {
Collection<V> c = new ArrayList<V>();
- for (Iterator<V> i = iterator(); i.hasNext(); )
- c.add(i.next());
+ for (V v : this) {
+ c.add(v);
+ }
return c.toArray();
}
+
+ @NotNull
@Override
- public <T> T[] toArray(T[] a) {
+ public <T> T[] toArray(@NotNull T[] a) {
Collection<V> c = new ArrayList<V>();
- for (Iterator<V> i = iterator(); i.hasNext(); )
- c.add(i.next());
+ for (V v : this) {
+ c.add(v);
+ }
return c.toArray(a);
}
}
- final class EntrySet extends AbstractSet<Entry<K,V>> {
+ private final class EntrySet extends AbstractSet<Entry<K, V>> {
+ @NotNull
@Override
- public Iterator<Entry<K,V>> iterator() {
+ public Iterator<Entry<K, V>> iterator() {
return new EntryIterator();
}
+
@Override
public boolean contains(Object o) {
- if (!(o instanceof Entry))
+ if (!(o instanceof Entry)) {
return false;
- Entry<K,V> e = (Entry<K,V>)o;
+ }
+ Entry<K, V> e = (Entry<K, V>)o;
V v = get(e.getKey());
return v != null && v.equals(e.getValue());
}
+
@Override
public boolean remove(Object o) {
- if (!(o instanceof Entry))
+ if (!(o instanceof Entry)) {
return false;
- Entry<K,V> e = (Entry<K,V>)o;
+ }
+ Entry<K, V> e = (Entry<K, V>)o;
return ConcurrentHashMap.this.remove(e.getKey(), e.getValue());
}
+
@Override
public int size() {
return ConcurrentHashMap.this.size();
}
+
@Override
public void clear() {
ConcurrentHashMap.this.clear();
}
+
+ @NotNull
@Override
public Object[] toArray() {
// Since we don't ordinarily have distinct Entry objects, we
// must pack elements using exportable SimpleEntry
- Collection<Entry<K,V>> c = new ArrayList<Entry<K,V>>(size());
- for (Iterator<Entry<K,V>> i = iterator(); i.hasNext(); )
- c.add(new SimpleEntry(i.next()));
+ Collection<Entry<K, V>> c = new ArrayList<Entry<K, V>>(size());
+ for (Entry<K, V> entry : this) {
+ c.add(new SimpleEntry(entry));
+ }
return c.toArray();
}
+
+ @NotNull
@Override
- public <T> T[] toArray(T[] a) {
- Collection<Entry<K,V>> c = new ArrayList<Entry<K,V>>(size());
- for (Iterator<Entry<K,V>> i = iterator(); i.hasNext(); )
- c.add(new SimpleEntry(i.next()));
+ public <T> T[] toArray(@NotNull T[] a) {
+ Collection<Entry<K, V>> c = new ArrayList<Entry<K, V>>(size());
+ for (Entry<K, V> entry : this) {
+ c.add(new SimpleEntry(entry));
+ }
return c.toArray(a);
}
-
}
/**
* This duplicates java.util.AbstractMap.SimpleEntry until this class
* is made accessible.
*/
- final class SimpleEntry implements Entry<K,V> {
- K key;
- V value;
+ final class SimpleEntry implements Entry<K, V> {
+ private final K key;
+ private V value;
public SimpleEntry(K key, V value) {
- this.key = key;
+ this.key = key;
this.value = value;
}
- public SimpleEntry(Entry<K,V> e) {
+ public SimpleEntry(Entry<K, V> e) {
key = e.getKey();
value = e.getValue();
}
@@ -1321,16 +1423,16 @@
}
public boolean equals(Object o) {
- if (!(o instanceof Entry))
+ if (!(o instanceof Entry)) {
return false;
+ }
Entry e = (Entry)o;
K o2 = (K)e.getKey();
- return (key == null ? o2 == null : myHashingStrategy.equals(key,o2)) && eq(value, e.getValue());
+ return (key == null ? o2 == null : myHashingStrategy.equals(key, o2)) && eq(value, e.getValue());
}
public int hashCode() {
- return ((key == null) ? 0 : key.hashCode()) ^
- ((value == null) ? 0 : value.hashCode());
+ return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
}
public String toString() {
@@ -1338,7 +1440,7 @@
}
boolean eq(Object o1, Object o2) {
- return (o1 == null ? o2 == null : o1.equals(o2));
+ return o1 == null ? o2 == null : o1.equals(o2);
}
}
@@ -1348,27 +1450,28 @@
* Save the state of the <tt>ConcurrentHashMap</tt>
* instance to a stream (i.e.,
* serialize it).
+ *
* @param s the stream
- * @serialData
- * the key (Object) and value (Object)
+ * @serialData the key (Object) and value (Object)
* for each key-value mapping, followed by a null pair.
* The key-value mappings are emitted in no particular order.
*/
- private void writeObject(java.io.ObjectOutputStream s) throws IOException {
+ private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
- for (int k = 0; k < segments.length; ++k) {
- Segment seg = segments[k];
+ for (Segment seg : segments) {
seg.lock();
try {
HashEntry[] tab = seg.table;
- for (int i = 0; i < tab.length; ++i) {
- for (HashEntry<K,V> e = (HashEntry<K,V>)tab[i]; e != null; e = e.next) {
+ for (HashEntry tabEntry : tab) {
+ HashEntry<K, V> entry = (HashEntry<K, V>)tabEntry;
+ for (HashEntry<K, V> e = entry; e != null; e = e.next) {
s.writeObject(e.key);
s.writeObject(e.value);
}
}
- } finally {
+ }
+ finally {
seg.unlock();
}
}
@@ -1380,23 +1483,25 @@
* Reconstitute the <tt>ConcurrentHashMap</tt>
* instance from a stream (i.e.,
* deserialize it).
+ *
* @param s the stream
*/
- private void readObject(java.io.ObjectInputStream s)
- throws IOException, ClassNotFoundException {
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
s.defaultReadObject();
// Initialize each segment to be minimally sized, and let grow.
- for (int i = 0; i < segments.length; ++i) {
- segments[i].setTable(new HashEntry[1]);
+ for (Segment segment : segments) {
+ segment.setTable(new HashEntry[1]);
}
// Read the keys and values, and put the mappings in the table
- for (;;) {
- K key = (K) s.readObject();
- V value = (V) s.readObject();
- if (key == null)
+ while (true) {
+ K key = (K)s.readObject();
+ V value = (V)s.readObject();
+ if (key == null) {
break;
+ }
put(key, value);
}
}
@@ -1405,9 +1510,9 @@
public int computeHashCode(final K object) {
int h = object.hashCode();
h += ~(h << 9);
- h ^= (h >>> 14);
- h += (h << 4);
- h ^= (h >>> 10);
+ h ^= h >>> 14;
+ h += h << 4;
+ h ^= h >>> 10;
return h;
}
diff --git a/platform/util/src/com/intellij/util/containers/ConcurrentHashSet.java b/platform/util/src/com/intellij/util/containers/ConcurrentHashSet.java
index 3db9eff..59a2240 100644
--- a/platform/util/src/com/intellij/util/containers/ConcurrentHashSet.java
+++ b/platform/util/src/com/intellij/util/containers/ConcurrentHashSet.java
@@ -17,6 +17,7 @@
package com.intellij.util.containers;
import gnu.trove.TObjectHashingStrategy;
+import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Iterator;
@@ -32,47 +33,60 @@
public ConcurrentHashSet() {
map = new ConcurrentHashMap<K, Boolean>();
}
- public ConcurrentHashSet(TObjectHashingStrategy<K> hashingStrategy) {
+ public ConcurrentHashSet(@NotNull TObjectHashingStrategy<K> hashingStrategy) {
map = new ConcurrentHashMap<K, Boolean>(hashingStrategy);
}
+ @Override
public int size() {
return map.size();
}
+ @Override
public boolean isEmpty() {
return map.isEmpty();
}
+ @Override
public boolean contains(Object o) {
return map.containsKey(o);
}
+ @NotNull
+ @Override
public Iterator<K> iterator() {
return map.keySet().iterator();
}
+ @NotNull
+ @Override
public Object[] toArray() {
return map.keySet().toArray();
}
- public <T> T[] toArray(T[] a) {
+ @NotNull
+ @Override
+ public <T> T[] toArray(@NotNull T[] a) {
return map.keySet().toArray(a);
}
+ @Override
public boolean add(K o) {
return map.putIfAbsent(o, Boolean.TRUE) == null;
}
+ @Override
public boolean remove(Object o) {
return map.keySet().remove(o);
}
- public boolean containsAll(Collection<?> c) {
+ @Override
+ public boolean containsAll(@NotNull Collection<?> c) {
return map.keySet().containsAll(c);
}
- public boolean addAll(Collection<? extends K> c) {
+ @Override
+ public boolean addAll(@NotNull Collection<? extends K> c) {
boolean ret = false;
for (K o : c) {
ret |= add(o);
@@ -81,14 +95,17 @@
return ret;
}
- public boolean retainAll(Collection<?> c) {
+ @Override
+ public boolean retainAll(@NotNull Collection<?> c) {
return map.keySet().retainAll(c);
}
- public boolean removeAll(Collection<?> c) {
+ @Override
+ public boolean removeAll(@NotNull Collection<?> c) {
return map.keySet().removeAll(c);
}
+ @Override
public void clear() {
map.clear();
}
diff --git a/platform/util/src/com/intellij/util/containers/ConcurrentRefHashMap.java b/platform/util/src/com/intellij/util/containers/ConcurrentRefHashMap.java
index d589a77..469342e 100644
--- a/platform/util/src/com/intellij/util/containers/ConcurrentRefHashMap.java
+++ b/platform/util/src/com/intellij/util/containers/ConcurrentRefHashMap.java
@@ -22,6 +22,7 @@
*/
package com.intellij.util.containers;
+import com.intellij.util.IncorrectOperationException;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
@@ -33,31 +34,33 @@
/**
* Fully copied from java.util.WeakHashMap except "get" method optimization.
*/
-abstract class ConcurrentRefHashMap<K,V> extends AbstractMap<K,V> implements ConcurrentMap<K,V> {
- public interface Key<K, V>{
+abstract class ConcurrentRefHashMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>, TObjectHashingStrategy<K> {
+ protected final ReferenceQueue<K> myReferenceQueue = new ReferenceQueue<K>();
+ private final ConcurrentHashMap<Key<K, V>, V> myMap; // hashing strategy must be canonical, we compute corresponding hash codes using our own myHashingStrategy
+ @NotNull
+ private final TObjectHashingStrategy<K> myHashingStrategy;
+
+ public interface Key<K, V> {
K get();
+
V getValue();
+
// MUST work even with gced references for the code in processQueue to work
boolean equals(Object o);
+
int hashCode();
}
- protected abstract Key<K, V> createKey(@NotNull K key, V value);
+ protected abstract Key<K, V> createKey(@NotNull K key, V value, @NotNull TObjectHashingStrategy<K> hashingStrategy);
- private static class HardKey<K,V> implements Key<K,V> {
+ private static class HardKey<K, V> implements Key<K, V> {
private K myKey;
private int myHash;
- private final V value;
- public HardKey(K key, V value) {
- this.value = value;
- setKey(key);
- }
-
- private void setKey(K key) {
+ private void setKey(K key, final int hash) {
myKey = key;
- myHash = key == null ? 0 : key.hashCode();
+ myHash = hash;
}
@Override
@@ -67,7 +70,7 @@
@Override
public V getValue() {
- return value;
+ return null;
}
public boolean equals(Object o) {
@@ -85,68 +88,70 @@
}
}
- private final ConcurrentHashMap<Key<K, V>, V> myMap;
private static final Key NULL_KEY = new Key() {
@Override
- public Object get() { return null; }
+ public Object get() {
+ return null;
+ }
+
@Override
- public Object getValue() { return null; }
+ public Object getValue() {
+ return null;
+ }
};
- protected final ReferenceQueue<K> myReferenceQueue = new ReferenceQueue<K>();
-
+ // returns true if some keys were processed
boolean processQueue() {
- Key<K,V> wk;
+ Key<K, V> wk;
boolean processed = false;
- while((wk = (Key)myReferenceQueue.poll()) != null){
+ while ((wk = (Key)myReferenceQueue.poll()) != null) {
V value = wk.getValue();
- myMap.remove(wk, wk.hashCode(), value);
+ myMap.remove(wk, value);
processed = true;
}
return processed;
}
- public ConcurrentRefHashMap(int initialCapacity, float loadFactor) {
- myMap = new ConcurrentHashMap<Key<K, V>, V>(initialCapacity, loadFactor, 4);
- }
-
- public ConcurrentRefHashMap(int initialCapacity) {
- myMap = new ConcurrentHashMap<Key<K, V>, V>(initialCapacity);
- }
-
- public ConcurrentRefHashMap() {
- myMap = new ConcurrentHashMap<Key<K, V>, V>();
- }
-
- public ConcurrentRefHashMap(int initialCapacity, float loadFactor, int concurrencyLevel, @NotNull TObjectHashingStrategy<K> hashingStrategy) {
- myMap = new ConcurrentHashMap<Key<K, V>, V>(initialCapacity, loadFactor, concurrencyLevel, ConcurrentRefHashMap.<K,V>convertKToKeyK(hashingStrategy));
- }
-
public ConcurrentRefHashMap(Map<? extends K, ? extends V> t) {
- this(Math.max(2 * t.size(), 11), 0.75f);
+ this(Math.max(2 * t.size(), 11), ConcurrentHashMap.DEFAULT_LOAD_FACTOR);
putAll(t);
}
+ public ConcurrentRefHashMap() {
+ this(ConcurrentHashMap.DEFAULT_INITIAL_CAPACITY);
+ }
+
+ public ConcurrentRefHashMap(int initialCapacity) {
+ this(initialCapacity, ConcurrentHashMap.DEFAULT_LOAD_FACTOR);
+ }
+
+ private static final TObjectHashingStrategy THIS = new TObjectHashingStrategy() {
+ @Override
+ public int computeHashCode(Object object) {
+ throw new IncorrectOperationException();
+ }
+
+ @Override
+ public boolean equals(Object o1, Object o2) {
+ throw new IncorrectOperationException();
+ }
+ };
+ public ConcurrentRefHashMap(int initialCapacity, float loadFactor) {
+ this(initialCapacity, loadFactor, 4, THIS);
+ }
+
public ConcurrentRefHashMap(@NotNull final TObjectHashingStrategy<K> hashingStrategy) {
- myMap = new ConcurrentHashMap<Key<K, V>, V>(ConcurrentRefHashMap.<K,V>convertKToKeyK(hashingStrategy));
+ this(ConcurrentHashMap.DEFAULT_INITIAL_CAPACITY, ConcurrentHashMap.DEFAULT_LOAD_FACTOR, 2, hashingStrategy);
}
- @NotNull
- private static <K,V> TObjectHashingStrategy<Key<K, V>> convertKToKeyK(@NotNull final TObjectHashingStrategy<K> hashingStrategy) {
- return new TObjectHashingStrategy<Key<K, V>>() {
- @Override
- public int computeHashCode(final Key<K, V> object) {
- return hashingStrategy.computeHashCode(object.get());
- }
-
- @Override
- public boolean equals(final Key<K, V> o1, final Key<K, V> o2) {
- return hashingStrategy.equals(o1.get(), o2.get());
- }
- };
+ public ConcurrentRefHashMap(int initialCapacity,
+ float loadFactor,
+ int concurrencyLevel,
+ @NotNull TObjectHashingStrategy<K> hashingStrategy) {
+ myHashingStrategy = hashingStrategy == THIS ? this : hashingStrategy;
+ myMap = new ConcurrentHashMap<Key<K, V>, V>(initialCapacity, loadFactor, concurrencyLevel, CANONICAL);
}
-
@Override
public int size() {
return entrySet().size();
@@ -160,40 +165,40 @@
@Override
public boolean containsKey(Object key) {
// optimization:
- if (key == null){
+ if (key == null) {
return myMap.containsKey(NULL_KEY);
}
- HardKey<K,V> hardKey = createHardKey((K)key);
+ HardKey<K, V> hardKey = createHardKey((K)key);
boolean result = myMap.containsKey(hardKey);
releaseHardKey(hardKey);
return result;
}
- private static final ThreadLocal<HardKey> HARD_KEY = new ThreadLocal<HardKey>(){
+ private static final ThreadLocal<HardKey> HARD_KEY = new ThreadLocal<HardKey>() {
@Override
protected HardKey initialValue() {
- return new HardKey(null, null);
+ return new HardKey();
}
};
- private static <K,V> HardKey<K,V> createHardKey(K key) {
+ private HardKey<K, V> createHardKey(K key) {
HardKey hardKey = HARD_KEY.get();
- hardKey.setKey(key);
+ hardKey.setKey(key, myHashingStrategy.computeHashCode(key));
return hardKey;
}
private static void releaseHardKey(HardKey key) {
- key.setKey(null);
+ key.setKey(null, 0);
}
@Override
public V get(Object key) {
//return myMap.get(WeakKey.create(key));
// optimization:
- if (key == null){
+ if (key == null) {
return myMap.get(NULL_KEY);
}
- HardKey<K,V> hardKey = createHardKey((K)key);
+ HardKey<K, V> hardKey = createHardKey((K)key);
V result = myMap.get(hardKey);
releaseHardKey(hardKey);
return result;
@@ -202,7 +207,7 @@
@Override
public V put(K key, V value) {
processQueue();
- Key<K, V> weakKey = key == null ? NULL_KEY : createKey(key, value);
+ Key<K, V> weakKey = key == null ? NULL_KEY : createKey(key, value, myHashingStrategy);
return myMap.put(weakKey, value);
}
@@ -211,10 +216,10 @@
processQueue();
// optimization:
- if (key == null){
+ if (key == null) {
return myMap.remove(NULL_KEY);
}
- HardKey hardKey = createHardKey(key);
+ HardKey hardKey = createHardKey((K)key);
V result = myMap.remove(hardKey);
releaseHardKey(hardKey);
return result;
@@ -226,13 +231,13 @@
myMap.clear();
}
- private static class Entry<K,V> implements Map.Entry<K,V> {
- private final Map.Entry<?,V> ent;
- private final K key; /* Strong reference to key, so that the GC
+ private static class RefEntry<K, V> implements Map.Entry<K, V> {
+ private final Map.Entry<?, V> ent;
+ private final K key; /* Strong reference to key, so that the GC
will leave it alone as long as this Entry
exists */
- Entry(Map.Entry<?,V> ent, K key) {
+ RefEntry(Map.Entry<?, V> ent, K key) {
this.ent = ent;
this.key = key;
}
@@ -269,27 +274,27 @@
}
/* Internal class for entry sets */
- private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
- Set<Map.Entry<Key<K, V>,V>> hashEntrySet = myMap.entrySet();
+ private class EntrySet extends AbstractSet<Map.Entry<K, V>> {
+ Set<Map.Entry<Key<K, V>, V>> hashEntrySet = myMap.entrySet();
@NotNull
@Override
- public Iterator<Map.Entry<K,V>> iterator() {
- return new Iterator<Map.Entry<K,V>>() {
- Iterator<Map.Entry<Key<K, V>,V>> hashIterator = hashEntrySet.iterator();
- Entry<K,V> next = null;
+ public Iterator<Map.Entry<K, V>> iterator() {
+ return new Iterator<Map.Entry<K, V>>() {
+ Iterator<Map.Entry<Key<K, V>, V>> hashIterator = hashEntrySet.iterator();
+ RefEntry<K, V> next = null;
@Override
public boolean hasNext() {
- while(hashIterator.hasNext()){
+ while (hashIterator.hasNext()) {
Map.Entry<Key<K, V>, V> ent = hashIterator.next();
Key<K, V> wk = ent.getKey();
K k = null;
- if (wk != null && (k = wk.get()) == null){
+ if (wk != null && (k = wk.get()) == null) {
/* Weak key has been cleared by GC */
continue;
}
- next = new Entry<K,V>(ent, k);
+ next = new RefEntry<K, V>(ent, k);
return true;
}
return false;
@@ -300,7 +305,7 @@
if (next == null && !hasNext()) {
throw new NoSuchElementException();
}
- Entry<K,V> e = next;
+ RefEntry<K, V> e = next;
next = null;
return e;
}
@@ -320,7 +325,7 @@
@Override
public int size() {
int j = 0;
- for(Iterator i = iterator(); i.hasNext(); i.next()) j++;
+ for (Iterator i = iterator(); i.hasNext(); i.next()) j++;
return j;
}
@@ -328,14 +333,14 @@
public boolean remove(Object o) {
processQueue();
if (!(o instanceof Map.Entry)) return false;
- Map.Entry e = (Map.Entry)o;
- Object ev = e.getValue();
+ Map.Entry<K,V> e = (Map.Entry)o;
+ V ev = e.getValue();
- HardKey key = createHardKey(o);
+ HardKey key = createHardKey(e.getKey());
V hv = myMap.get(key);
boolean toRemove = hv == null ? ev == null && myMap.containsKey(key) : hv.equals(ev);
- if (toRemove){
+ if (toRemove) {
myMap.remove(key);
}
@@ -354,14 +359,13 @@
}
return h;
}
-
}
- private Set<Map.Entry<K,V>> entrySet = null;
+ private Set<Map.Entry<K, V>> entrySet = null;
@NotNull
@Override
- public Set<Map.Entry<K,V>> entrySet() {
+ public Set<Map.Entry<K, V>> entrySet() {
if (entrySet == null) entrySet = new EntrySet();
return entrySet;
}
@@ -369,25 +373,41 @@
@Override
public V putIfAbsent(@NotNull final K key, final V value) {
processQueue();
- return myMap.putIfAbsent(createKey(key, value), value);
+ return myMap.putIfAbsent(createKey(key, value, myHashingStrategy), value);
}
@Override
public boolean remove(@NotNull final Object key, final Object value) {
processQueue();
- return myMap.remove(createKey((K)key, (V)value), value);
+ return myMap.remove(createKey((K)key, (V)value, myHashingStrategy), value);
}
@Override
public boolean replace(@NotNull final K key, @NotNull final V oldValue, @NotNull final V newValue) {
processQueue();
- return myMap.replace(createKey(key, oldValue), oldValue,newValue);
+ return myMap.replace(createKey(key, oldValue, myHashingStrategy), oldValue, newValue);
}
@Override
public V replace(@NotNull final K key, @NotNull final V value) {
processQueue();
- return myMap.replace(createKey(key, value), value);
+ return myMap.replace(createKey(key, value, myHashingStrategy), value);
+ }
+
+ // MAKE SURE IT CONSISTENT WITH com.intellij.util.containers.ConcurrentHashMap
+ @Override
+ public int computeHashCode(final K object) {
+ int h = object.hashCode();
+ h += ~(h << 9);
+ h ^= (h >>> 14);
+ h += (h << 4);
+ h ^= (h >>> 10);
+ return h;
+ }
+
+ @Override
+ public boolean equals(final K o1, final K o2) {
+ return o1.equals(o2);
}
@TestOnly
diff --git a/platform/util/src/com/intellij/util/containers/ConcurrentRefValueHashMap.java b/platform/util/src/com/intellij/util/containers/ConcurrentRefValueHashMap.java
index 61a3556..41f3d9c 100644
--- a/platform/util/src/com/intellij/util/containers/ConcurrentRefValueHashMap.java
+++ b/platform/util/src/com/intellij/util/containers/ConcurrentRefValueHashMap.java
@@ -19,14 +19,15 @@
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.TestOnly;
import java.lang.ref.ReferenceQueue;
import java.util.*;
import java.util.HashSet;
import java.util.concurrent.ConcurrentMap;
-abstract class ConcurrentRefValueHashMap<K,V> implements ConcurrentMap<K,V> {
- private final ConcurrentHashMap<K,MyValueReference<K, V>> myMap;
+abstract class ConcurrentRefValueHashMap<K, V> implements ConcurrentMap<K, V> {
+ private final ConcurrentHashMap<K, MyValueReference<K, V>> myMap;
protected final ReferenceQueue<V> myQueue = new ReferenceQueue<V>();
public ConcurrentRefValueHashMap(@NotNull Map<K, V> map) {
@@ -37,25 +38,35 @@
public ConcurrentRefValueHashMap() {
myMap = new ConcurrentHashMap<K, MyValueReference<K, V>>();
}
+
public ConcurrentRefValueHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) {
myMap = new ConcurrentHashMap<K, MyValueReference<K, V>>(initialCapacity, loadFactor, concurrencyLevel);
}
- public ConcurrentRefValueHashMap(int initialCapacity, float loadFactor, int concurrencyLevel, @NotNull TObjectHashingStrategy<K> hashingStrategy) {
+
+ public ConcurrentRefValueHashMap(int initialCapacity,
+ float loadFactor,
+ int concurrencyLevel,
+ @NotNull TObjectHashingStrategy<K> hashingStrategy) {
myMap = new ConcurrentHashMap<K, MyValueReference<K, V>>(initialCapacity, loadFactor, concurrencyLevel, hashingStrategy);
}
protected interface MyValueReference<K, V> {
@NotNull
K getKey();
+
V get();
}
- private void processQueue() {
- while(true){
+ boolean processQueue() {
+ boolean processed = false;
+
+ while (true) {
MyValueReference<K, V> ref = (MyValueReference<K, V>)myQueue.poll();
if (ref == null) break;
myMap.remove(ref.getKey(), ref);
+ processed = true;
}
+ return processed;
}
@Override
@@ -210,9 +221,14 @@
@NonNls String s = "map size:" + size() + " [";
for (K k : myMap.keySet()) {
Object v = get(k);
- s += "'"+k + "': '" +v+"', ";
+ s += "'" + k + "': '" + v + "', ";
}
s += "] ";
return s;
}
+
+ @TestOnly
+ int underlyingMapSize() {
+ return myMap.size();
+ }
}
diff --git a/platform/util/src/com/intellij/util/containers/ConcurrentSoftHashMap.java b/platform/util/src/com/intellij/util/containers/ConcurrentSoftHashMap.java
index cd028d2..0bd2122 100644
--- a/platform/util/src/com/intellij/util/containers/ConcurrentSoftHashMap.java
+++ b/platform/util/src/com/intellij/util/containers/ConcurrentSoftHashMap.java
@@ -29,15 +29,15 @@
import java.lang.ref.SoftReference;
import java.util.Map;
-public final class ConcurrentSoftHashMap<K,V> extends ConcurrentRefHashMap<K,V> {
+public final class ConcurrentSoftHashMap<K, V> extends ConcurrentRefHashMap<K, V> {
private static class SoftKey<K, V> extends SoftReference<K> implements ConcurrentRefHashMap.Key<K, V> {
- private final int myHash; /* Hashcode of key, stored here since the key may be tossed by the GC */
+ private final int myHash; // Hashcode of key, stored here since the key may be tossed by the GC
private final V value;
- private SoftKey(@NotNull K k, V v, ReferenceQueue<K> q) {
+ private SoftKey(@NotNull K k, final int hash, V v, @NotNull ReferenceQueue<K> q) {
super(k, q);
value = v;
- myHash = k.hashCode();
+ myHash = hash;
}
@Override
@@ -47,11 +47,11 @@
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof ConcurrentRefHashMap.Key)) return false;
+ if (!(o instanceof Key)) return false;
Object t = get();
- Object u = ((ConcurrentRefHashMap.Key)o).get();
- if (t == null || u == null) return false;
+ Object u = ((Key)o).get();
if (t == u) return true;
+ if (t == null || u == null) return false;
return t.equals(u);
}
@@ -61,8 +61,8 @@
}
@Override
- protected ConcurrentRefHashMap.Key<K, V> createKey(@NotNull K key, V value) {
- return new SoftKey<K, V>(key, value, myReferenceQueue);
+ protected ConcurrentRefHashMap.Key<K, V> createKey(@NotNull K key, V value, @NotNull TObjectHashingStrategy<K> hashingStrategy) {
+ return new SoftKey<K, V>(key, hashingStrategy.computeHashCode(key), value, myReferenceQueue);
}
public ConcurrentSoftHashMap(int initialCapacity, float loadFactor) {
diff --git a/platform/util/src/com/intellij/util/containers/ConcurrentWeakHashMap.java b/platform/util/src/com/intellij/util/containers/ConcurrentWeakHashMap.java
index 93cc863..44c5408 100644
--- a/platform/util/src/com/intellij/util/containers/ConcurrentWeakHashMap.java
+++ b/platform/util/src/com/intellij/util/containers/ConcurrentWeakHashMap.java
@@ -32,15 +32,15 @@
/**
* Fully copied from java.util.WeakHashMap except "get" method optimization.
*/
-public final class ConcurrentWeakHashMap<K,V> extends ConcurrentRefHashMap<K,V> {
+public final class ConcurrentWeakHashMap<K, V> extends ConcurrentRefHashMap<K, V> {
private static class WeakKey<K, V> extends WeakReference<K> implements Key<K, V> {
private final int myHash; /* Hashcode of key, stored here since the key may be tossed by the GC */
private final V value;
- private WeakKey(@NotNull K k, V v, ReferenceQueue<K> q) {
+ private WeakKey(@NotNull K k, final int hash, V v, ReferenceQueue<K> q) {
super(k, q);
value = v;
- myHash = k.hashCode();
+ myHash = hash;
}
@Override
@@ -64,8 +64,8 @@
}
@Override
- protected Key<K, V> createKey(@NotNull K key, V value) {
- return new WeakKey<K, V>(key, value, myReferenceQueue);
+ protected Key<K, V> createKey(@NotNull K key, V value, @NotNull TObjectHashingStrategy<K> hashingStrategy) {
+ return new WeakKey<K, V>(key, hashingStrategy.computeHashCode(key), value, myReferenceQueue);
}
public ConcurrentWeakHashMap(int initialCapacity, float loadFactor) {
diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
index bf98ac2..87460f5 100644
--- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java
+++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
@@ -54,6 +54,11 @@
}
@NotNull
+ public static <K, V> Map<K, V> newHashMap(Pair<K, V> first, Pair<K, V>... entries) {
+ return ContainerUtilRt.newHashMap(first, entries);
+ }
+
+ @NotNull
public static <K, V> Map<K, V> newHashMap(@NotNull List<K> keys, @NotNull List<V> values) {
return ContainerUtilRt.newHashMap(keys, values);
}
@@ -1029,6 +1034,15 @@
}
/**
+ * @param appendTail specify whether additional values should be appended in front or after the list
+ * @return read-only list consisting of the elements from specified list with some additional values
+ */
+ @NotNull
+ public static <T> List<T> concat(boolean appendTail, @NotNull List<? extends T> list, T... values) {
+ return appendTail ? concat(list, list(values)) : concat(list(values), list);
+ }
+
+ /**
* @return read-only list consisting of the two lists added together
*/
@NotNull
diff --git a/platform/util/src/com/intellij/util/io/BooleanDataDescriptor.java b/platform/util/src/com/intellij/util/io/BooleanDataDescriptor.java
index 1b5531b..bc5e668 100644
--- a/platform/util/src/com/intellij/util/io/BooleanDataDescriptor.java
+++ b/platform/util/src/com/intellij/util/io/BooleanDataDescriptor.java
@@ -31,4 +31,8 @@
public int toInt(Boolean aBoolean) {
return aBoolean == Boolean.TRUE ? 1 : 0;
}
+
+ protected boolean isCompactFormat() {
+ return true;
+ }
}
diff --git a/platform/util/src/com/intellij/util/io/DataOutputStream.java b/platform/util/src/com/intellij/util/io/DataOutputStream.java
index 97ee34b..67097e1 100644
--- a/platform/util/src/com/intellij/util/io/DataOutputStream.java
+++ b/platform/util/src/com/intellij/util/io/DataOutputStream.java
@@ -34,4 +34,14 @@
out.write(b, off, len);
written += len;
}
+
+ public int getWrittenBytesCount() {
+ return written;
+ }
+
+ public int resetWrittenBytesCount() {
+ int result = written;
+ written = 0;
+ return result;
+ }
}
diff --git a/platform/util/src/com/intellij/util/io/InlineKeyDescriptor.java b/platform/util/src/com/intellij/util/io/InlineKeyDescriptor.java
index 7dfe1f4..715c496 100644
--- a/platform/util/src/com/intellij/util/io/InlineKeyDescriptor.java
+++ b/platform/util/src/com/intellij/util/io/InlineKeyDescriptor.java
@@ -24,6 +24,12 @@
import java.io.IOException;
public abstract class InlineKeyDescriptor<T> implements KeyDescriptor<T> {
+ private final boolean myCompactFormat = isCompactFormat();
+
+ protected boolean isCompactFormat() {
+ return false;
+ }
+
public final int getHashCode(T value) {
return toInt(value);
}
@@ -33,11 +39,16 @@
}
public final void save(DataOutput out, T value) throws IOException {
- out.writeInt(toInt(value));
+ int v = toInt(value);
+ if (myCompactFormat) DataInputOutputUtil.writeINT(out, v);
+ else out.writeInt(v);
}
public final T read(DataInput in) throws IOException {
- return fromInt(in.readInt());
+ int n;
+ if (myCompactFormat) n = DataInputOutputUtil.readINT(in);
+ else n = in.readInt();
+ return fromInt(n);
}
public abstract T fromInt(int n);
diff --git a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java
index 751f55e..adbd305 100644
--- a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java
+++ b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java
@@ -60,7 +60,7 @@
private boolean myExternalKeysNoMapping;
private static final int DIRTY_MAGIC = 0xbabe1977;
- private static final int VERSION = 6 + IntToIntBtree.version();
+ private static final int VERSION = 7 + IntToIntBtree.version();
private static final int CORRECTLY_CLOSED_MAGIC = 0xebabafc + VERSION + PAGE_SIZE;
@NotNull private static final Version ourVersion = new Version(CORRECTLY_CLOSED_MAGIC, DIRTY_MAGIC);
private static final int KEY_SHIFT = 1;
diff --git a/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java b/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java
index 363a75b..543483c 100644
--- a/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java
+++ b/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java
@@ -39,7 +39,7 @@
* @author jeka
*/
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
-abstract class PersistentEnumeratorBase<Data> implements Forceable, Closeable {
+abstract public class PersistentEnumeratorBase<Data> implements Forceable, Closeable {
protected static final Logger LOG = Logger.getInstance("#com.intellij.util.io.PersistentEnumerator");
protected static final int NULL_ID = 0;
@@ -427,10 +427,14 @@
comparer.close();
if (sameValue[0]) return true;
-
+ if (serializationEquivalenceIsExhausting()) return false;
return myDataDescriptor.isEqual(valueOf(idx), value);
}
+ protected boolean serializationEquivalenceIsExhausting() {
+ return false;
+ }
+
protected int writeData(final Data value, int hashCode) {
try {
markDirty(true);
@@ -498,7 +502,7 @@
return pos;
}
- protected boolean iterateData(final Processor<Data> processor) throws IOException {
+ public boolean iterateData(final Processor<Data> processor) throws IOException {
lockStorage();
try {
if (myKeyStorage == null) {
@@ -509,7 +513,12 @@
myKeyStorage.force();
DataInputStream keysStream = new DataInputStream(new BufferedInputStream(new LimitedInputStream(new FileInputStream(keystreamFile()),
- myKeyStoreFileLength)));
+ myKeyStoreFileLength) {
+ @Override
+ public int available() throws IOException {
+ return remainingLimit();
+ }
+ }, 32768));
try {
try {
while (true) {
diff --git a/platform/util/src/com/intellij/util/io/PersistentHashMapValueStorage.java b/platform/util/src/com/intellij/util/io/PersistentHashMapValueStorage.java
index 6725c21..8c50529 100644
--- a/platform/util/src/com/intellij/util/io/PersistentHashMapValueStorage.java
+++ b/platform/util/src/com/intellij/util/io/PersistentHashMapValueStorage.java
@@ -88,16 +88,6 @@
}
}
- private long smallWrites;
- private int smallWritesCount;
- private long largeWrites;
- private int largeWritesCount;
- private int requests;
-
- private static final int POSITIVE_VALUE_SHIFT = 1;
- private static final int BYTE_LENGTH_INT_ADDRESS = 1 + 4;
- private static final int INT_LENGTH_LONG_ADDRESS = 4 + 8;
-
public long appendBytes(ByteSequence data, long prevChunkAddress) throws IOException {
return appendBytes(data.getBytes(), data.getOffset(), data.getLength(), prevChunkAddress);
}
@@ -106,40 +96,28 @@
assert !myCompactionMode;
long result = mySize; // volatile read
final CacheValue<DataOutputStream> appender = ourAppendersCache.get(myPath);
- int serviceFieldsSizeIncrease;
+ DataOutputStream dataOutputStream;
try {
- DataOutputStream dataOutputStream = appender.get();
- ++requests;
-
- if (dataLength + POSITIVE_VALUE_SHIFT < 0x80 && prevChunkAddress < Integer.MAX_VALUE) {
- ++smallWritesCount;
- smallWrites += dataLength;
- dataOutputStream.write(-dataLength - POSITIVE_VALUE_SHIFT);
- dataOutputStream.writeInt((int)prevChunkAddress);
- serviceFieldsSizeIncrease = BYTE_LENGTH_INT_ADDRESS;
- } else {
- ++largeWritesCount;
- largeWrites += dataLength;
- dataOutputStream.writeInt(dataLength);
- dataOutputStream.writeLong(prevChunkAddress);
- serviceFieldsSizeIncrease = INT_LENGTH_LONG_ADDRESS;
- }
+ dataOutputStream = appender.get();
+ dataOutputStream.resetWrittenBytesCount();
+
+ DataInputOutputUtil.writeINT(dataOutputStream, dataLength);
+ writePrevChunkAddress(prevChunkAddress, result, dataOutputStream);
+
dataOutputStream.write(data, offset, dataLength);
- if (IOStatistics.DEBUG && (requests % IOStatistics.KEYS_FACTOR_MASK) == 0) {
- IOStatistics.dump("Small writes:"+smallWritesCount +", bytes:"+smallWrites + ", largeWrites:"+largeWritesCount
- + ", bytes:"+largeWrites+", total:"+requests + "@"+myFile.getPath());
- }
+ mySize += dataOutputStream.resetWrittenBytesCount(); // volatile write
}
finally {
appender.release();
}
- mySize += dataLength + serviceFieldsSizeIncrease; // volatile write
return result;
}
private final byte[] myBuffer = new byte[1024];
+ private final UnsyncByteArrayInputStream myBufferStreamWrapper = new UnsyncByteArrayInputStream(myBuffer);
+ private final DataInputStream myBufferDataStreamWrapper = new DataInputStream(myBufferStreamWrapper);
public int compactValues(List<PersistentHashMap.CompactionRecordInfo> infos, PersistentHashMapValueStorage storage) throws IOException {
PriorityQueue<PersistentHashMap.CompactionRecordInfo> records = new PriorityQueue<PersistentHashMap.CompactionRecordInfo>(
@@ -155,7 +133,7 @@
records.addAll(infos);
final int fileBufferLength = 256 * 1024;
- final int maxRecordHeader = Math.max(BYTE_LENGTH_INT_ADDRESS, INT_LENGTH_LONG_ADDRESS);
+ final int maxRecordHeader = 5 /* max length - variable int */ + 10 /* max long offset*/;
final byte[] buffer = new byte[fileBufferLength + maxRecordHeader];
byte[] recordBuffer = {};
@@ -184,7 +162,8 @@
// record start is inside our buffer
final int recordStartInBuffer = (int) (info.valueAddress - readStartOffset);
- final int sizePart = buffer[recordStartInBuffer];
+ myBufferStreamWrapper.init(buffer, recordStartInBuffer, buffer.length);
+
final long prevChunkAddress;
int chunkSize;
final int dataOffset;
@@ -201,15 +180,10 @@
}
}
- if (sizePart < 0) {
- chunkSize = -sizePart - POSITIVE_VALUE_SHIFT;
- prevChunkAddress = Bits.getInt(buffer, recordStartInBuffer + 1);
- dataOffset = BYTE_LENGTH_INT_ADDRESS;
- } else {
- chunkSize = Bits.getInt(buffer, recordStartInBuffer);
- prevChunkAddress = Bits.getLong(buffer, recordStartInBuffer + 4);
- dataOffset = INT_LENGTH_LONG_ADDRESS;
- }
+ int available = myBufferStreamWrapper.available();
+ chunkSize = DataInputOutputUtil.readINT(myBufferDataStreamWrapper);
+ prevChunkAddress = readPrevChunkAddress(info.valueAddress + (available - myBufferStreamWrapper.available()));
+ dataOffset = available - myBufferStreamWrapper.available();
byte[] b;
if (info.value != null) {
@@ -325,32 +299,21 @@
if (chunk < 0 || chunk > mySize) throw new PersistentEnumeratorBase.CorruptedException(myFile);
int len = (int)Math.min(myBuffer.length, mySize - chunk);
reader.get(chunk, myBuffer, 0, len);
+ myBufferStreamWrapper.init(myBuffer, 0, len);
- final int sizePart = myBuffer[0];
- final long prevChunkAddress;
- final int chunkSize;
+ final int chunkSize = DataInputOutputUtil.readINT(myBufferDataStreamWrapper);
+ final long prevChunkAddress = readPrevChunkAddress(chunk);
+ final int headerOffset = len - myBufferStreamWrapper.available();
- if (sizePart < 0) {
- chunkSize = -sizePart - POSITIVE_VALUE_SHIFT;
- prevChunkAddress = Bits.getInt(myBuffer, 1);
- byte[] b = new byte[(result != null ? result.length:0) + chunkSize];
- if (result != null) System.arraycopy(result, 0, b, b.length - result.length, result.length);
- result = b;
+ byte[] b = new byte[(result != null ? result.length:0) + chunkSize];
+ if (result != null) System.arraycopy(result, 0, b, b.length - result.length, result.length);
+ result = b;
- checkPreconditions(result, chunkSize, 0);
- System.arraycopy(myBuffer, BYTE_LENGTH_INT_ADDRESS, result, 0, chunkSize);
+ checkPreconditions(result, chunkSize, 0);
+ if (chunkSize < myBuffer.length - headerOffset) {
+ System.arraycopy(myBuffer, headerOffset, result, 0, chunkSize);
} else {
- chunkSize = Bits.getInt(myBuffer, 0);
- prevChunkAddress = Bits.getLong(myBuffer, 4);
- byte[] b = new byte[(result != null ? result.length:0) + chunkSize];
- if (result != null) System.arraycopy(result, 0, b, b.length - result.length, result.length);
- result = b;
-
- if (chunkSize < myBuffer.length - INT_LENGTH_LONG_ADDRESS) {
- System.arraycopy(myBuffer, INT_LENGTH_LONG_ADDRESS, result, 0, chunkSize);
- } else {
- reader.get(chunk + INT_LENGTH_LONG_ADDRESS, result, 0, chunkSize);
- }
+ reader.get(chunk + headerOffset, result, 0, chunkSize);
}
if (prevChunkAddress >= chunk) throw new PersistentEnumeratorBase.CorruptedException(myFile);
@@ -379,6 +342,26 @@
return new ReadResult(tailChunkAddress, result);
}
+ private long readPrevChunkAddress(long chunk) throws IOException {
+ final int prevOffsetDiff = DataInputOutputUtil.readINT(myBufferDataStreamWrapper);
+ if (prevOffsetDiff < 0) {
+ return chunk - (-prevOffsetDiff | ((long)DataInputOutputUtil.readINT(myBufferDataStreamWrapper) << 32));
+ }
+ assert prevOffsetDiff < chunk;
+ return prevOffsetDiff != 0 ? chunk - prevOffsetDiff : 0;
+ }
+
+ private static void writePrevChunkAddress(long prevChunkAddress, long currentChunkAddress, DataOutputStream dataOutputStream) throws IOException {
+ long diff = currentChunkAddress - prevChunkAddress;
+
+ if (diff < Integer.MAX_VALUE || prevChunkAddress == 0)
+ DataInputOutputUtil.writeINT(dataOutputStream, prevChunkAddress == 0 ? 0 : (int)diff);
+ else {
+ DataInputOutputUtil.writeINT(dataOutputStream, -(int)diff);
+ DataInputOutputUtil.writeINT(dataOutputStream, (int)(diff >>> 32));
+ }
+ }
+
public long getSize() {
return mySize;
}
diff --git a/platform/util/src/com/intellij/util/io/UnsyncByteArrayInputStream.java b/platform/util/src/com/intellij/util/io/UnsyncByteArrayInputStream.java
index 830a7e0..d35da96 100644
--- a/platform/util/src/com/intellij/util/io/UnsyncByteArrayInputStream.java
+++ b/platform/util/src/com/intellij/util/io/UnsyncByteArrayInputStream.java
@@ -22,7 +22,7 @@
public class UnsyncByteArrayInputStream extends InputStream {
protected byte[] myBuffer;
private int myPosition;
- private final int myCount;
+ private int myCount;
private int myMarkedPosition;
public UnsyncByteArrayInputStream(@NotNull byte[] buf) {
@@ -30,6 +30,10 @@
}
public UnsyncByteArrayInputStream(byte[] buf, int offset, int length) {
+ init(buf, offset, length);
+ }
+
+ public void init(byte[] buf, int offset, int length) {
myBuffer = buf;
myPosition = offset;
myCount = length;
diff --git a/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java b/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java
new file mode 100644
index 0000000..b89ef90
--- /dev/null
+++ b/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.util.containers;
+
+import gnu.trove.TObjectHashingStrategy;
+import junit.framework.TestCase;
+
+import java.lang.ref.SoftReference;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class ConcurrentMapsTest extends TestCase {
+ public void testKeysRemovedWhenIdentityStrategyIsUsed() {
+ ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>(TObjectHashingStrategy.IDENTITY);
+ map.put(new Object(), new Object());
+
+ do {
+ System.gc();
+ }
+ while (!map.processQueue());
+ map.put(this, this);
+ assertEquals(1, map.underlyingMapSize());
+ }
+
+ public void testRemoveFromSoftEntrySet() {
+ ConcurrentSoftHashMap<Object, Object> map = new ConcurrentSoftHashMap<Object, Object>();
+ map.put(this, this);
+ Set<Map.Entry<Object,Object>> entries = map.entrySet();
+ assertEquals(1, entries.size());
+ Map.Entry<Object, Object> entry = entries.iterator().next();
+ entries.remove(entry);
+
+ assertTrue(map.isEmpty());
+ }
+
+ public void testRemoveFromWeakEntrySet() {
+ ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>();
+ map.put(this, this);
+ Set<Map.Entry<Object,Object>> entries = map.entrySet();
+ assertEquals(1, entries.size());
+ Map.Entry<Object, Object> entry = entries.iterator().next();
+ entries.remove(entry);
+
+ assertTrue(map.isEmpty());
+ }
+
+ public void testTossedWeakKeysAreRemoved() {
+ ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>();
+ map.put(new Object(), new Object());
+
+ do {
+ System.gc();
+ }
+ while (!map.processQueue());
+ assertEquals(0, map.underlyingMapSize());
+ map.put(this, this);
+ assertEquals(1, map.underlyingMapSize());
+ }
+
+ public static void tryGcSoftlyReachableObjects() {
+ SoftReference reference = new SoftReference(new Object());
+ List<Object> list = ContainerUtil.newArrayList();
+ while (reference.get() != null) {
+ list.add(new SoftReference<byte[]>(new byte[(int)Runtime.getRuntime().freeMemory() / 2]));
+ }
+ }
+
+ public void testTossedSoftKeysAreRemoved() {
+ ConcurrentSoftHashMap<Object, Object> map = new ConcurrentSoftHashMap<Object, Object>();
+ map.put(new Object(), new Object());
+
+ tryGcSoftlyReachableObjects();
+ do {
+ System.gc();
+ }
+ while (!map.processQueue());
+ assertEquals(0, map.underlyingMapSize());
+ map.put(this, this);
+ assertEquals(1, map.underlyingMapSize());
+ }
+
+ public void testTossedWeakValueIsRemoved() {
+ ConcurrentWeakValueHashMap<Object, Object> map = new ConcurrentWeakValueHashMap<Object, Object>();
+ map.put(new Object(), new Object());
+
+ do {
+ System.gc();
+ }
+ while (!map.processQueue());
+ assertEquals(0, map.underlyingMapSize());
+ map.put(this, this);
+ assertEquals(1, map.underlyingMapSize());
+ }
+ public void testTossedSoftValueIsRemoved() {
+ ConcurrentSoftValueHashMap<Object, Object> map = new ConcurrentSoftValueHashMap<Object, Object>();
+ map.put(new Object(), new Object());
+
+ tryGcSoftlyReachableObjects();
+ do {
+ System.gc();
+ }
+ while (!map.processQueue());
+ assertEquals(0, map.underlyingMapSize());
+ map.put(this, this);
+ assertEquals(1, map.underlyingMapSize());
+ }
+}
diff --git a/platform/util/testSrc/com/intellij/util/containers/ConcurrentWeakHashMapTest.java b/platform/util/testSrc/com/intellij/util/containers/ConcurrentWeakHashMapTest.java
deleted file mode 100644
index c76d8ec6..0000000
--- a/platform/util/testSrc/com/intellij/util/containers/ConcurrentWeakHashMapTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.util.containers;
-
-import gnu.trove.TObjectHashingStrategy;
-import junit.framework.TestCase;
-
-public class ConcurrentWeakHashMapTest extends TestCase {
- public void testKeysRemovedWhenIdentityStrategyIsUsed() {
- ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>(TObjectHashingStrategy.IDENTITY);
- map.put(new Object(), new Object());
-
- do {
- System.gc();
- }
- while (!map.processQueue());
- map.put(this, this);
- assertEquals(1, map.underlyingMapSize());
- }
-}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
index a9ef16c..df28526 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
@@ -340,7 +340,7 @@
private Range getLastRangeBeforeLine(int line) {
Range result = null;
for (Range range : myRanges) {
- if (range.isMoreThen(line)) return result;
+ if (range.isAfter(line)) return result;
result = range;
}
return result;
@@ -439,7 +439,7 @@
if (prev.getHighlighter() != null) {
prev.getHighlighter().dispose();
}
- prev = prev.mergeWith(range, LineStatusTracker.this);
+ prev = prev.mergeWith(range);
}
else {
result.add(prev);
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java
index 219e330..6900d46 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java
@@ -19,12 +19,14 @@
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.util.diff.Diff;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* author: lesya
*/
public class Range {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.ex.Range");
+ private static final Logger LOG = Logger.getInstance(Range.class);
public static final byte MODIFIED = 1;
public static final byte INSERTED = 2;
public static final byte DELETED = 3;
@@ -34,10 +36,9 @@
private final int myUpToDateOffset1;
private final int myUpToDateOffset2;
private final byte myType;
- private RangeHighlighter myRangeHighlighter;
+ @Nullable private RangeHighlighter myRangeHighlighter;
- public static Range createOn(Diff.Change change, int shift, int upToDateShift) {
-
+ public static Range createOn(@NotNull Diff.Change change, int shift, int upToDateShift) {
byte type = getChangeTypeFrom(change);
int offset1 = shift + change.line1;
@@ -49,7 +50,7 @@
return new Range(offset1, offset2, uOffset1, uOffset2, type);
}
- private static byte getChangeTypeFrom(Diff.Change change) {
+ private static byte getChangeTypeFrom(@NotNull Diff.Change change) {
if ((change.deleted > 0) && (change.inserted > 0)) return MODIFIED;
if ((change.deleted > 0)) return DELETED;
if ((change.inserted > 0)) return INSERTED;
@@ -73,8 +74,7 @@
if (!(object instanceof Range)) return false;
Range other = (Range)object;
return
- (myOffset1 == other.myOffset1)
- && (myUpToDateOffset1 == other.myUpToDateOffset1)
+ (myUpToDateOffset1 == other.myUpToDateOffset1)
&& (myUpToDateOffset2 == other.myUpToDateOffset2)
&& (myOffset1 == other.myOffset1)
&& (myOffset2 == other.myOffset2)
@@ -82,20 +82,11 @@
}
public String toString() {
- StringBuffer result = new StringBuffer();
- result.append(String.valueOf(myOffset1));
- result.append(", ");
- result.append(String.valueOf(myOffset2));
- result.append(", ");
- result.append(String.valueOf(myUpToDateOffset1));
- result.append(", ");
- result.append(String.valueOf(myUpToDateOffset2));
- result.append(", ");
- result.append(getTypeName());
- return result.toString();
+ return String.format("%s, %s, %s, %s, %s", myOffset1, myOffset2, myUpToDateOffset1, myUpToDateOffset2, getTypeName());
}
- @NonNls private String getTypeName() {
+ @NonNls
+ private String getTypeName() {
switch (myType) {
case MODIFIED:
return "MODIFIED";
@@ -115,24 +106,11 @@
return myUpToDateOffset2 - myUpToDateOffset1;
}
- public boolean isInRange(int from, int to) {
- return (myOffset2 >= from && myOffset1 <= from) ||
- ((myOffset1 <= to) && (myOffset2 >= to));
- }
-
public void shift(int shift) {
myOffset1 += shift;
myOffset2 += shift;
}
- public boolean isAfter(int to) {
- return myOffset1 > to;
- }
-
- public int getCurrentLength() {
- return myOffset2 - myOffset1;
- }
-
public int getOffset1() {
return myOffset1;
}
@@ -149,17 +127,18 @@
return myUpToDateOffset2;
}
- public boolean canBeMergedWith(Range range) {
+ public boolean canBeMergedWith(@NotNull Range range) {
return myOffset2 == range.myOffset1;
}
- public Range mergeWith(Range range, LineStatusTracker tracker) {
+ @NotNull
+ public Range mergeWith(@NotNull Range range) {
return new Range(myOffset1, range.myOffset2, myUpToDateOffset1, range.myUpToDateOffset2, mergedStatusWith(range));
}
- private byte mergedStatusWith(Range range) {
+ private byte mergedStatusWith(@NotNull Range range) {
byte type = myType;
- if (myType != range.myType) type = Range.MODIFIED;
+ if (myType != range.myType) type = MODIFIED;
return type;
}
@@ -171,6 +150,7 @@
myRangeHighlighter = highlighter;
}
+ @Nullable
public RangeHighlighter getHighlighter() {
return myRangeHighlighter;
}
@@ -185,7 +165,7 @@
return myOffset1 <= line && myOffset2 >= line;
}
- public boolean isMoreThen(int line) {
+ public boolean isAfter(int line) {
if (myType == DELETED)
return (getOffset1() - 1) > line;
else
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java
index 0dba442..49e2e4a 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java
@@ -64,7 +64,7 @@
//Perhaps we always should have a root node 'Debugger' with separate nodes for language-specific settings under it.
//However for AppCode there is only one language which is clearly associated with the product
//This code should removed when we extract the common debugger settings to the root node.
- if (PlatformUtils.isAppCode() && rootConfigurable == null && configurables.size() == 1) {
+ if (PlatformUtils.isCidr() && rootConfigurable == null && configurables.size() == 1) {
rootConfigurable = configurables.get(0);
configurables = Collections.emptyList();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.java
index 4f25ccc92..57f9240 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.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,6 +26,7 @@
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.AppUIUtil;
import com.intellij.xdebugger.XSourcePosition;
@@ -44,6 +45,7 @@
private OpenFileDescriptor myOpenFileDescriptor;
private boolean myUseSelection;
private GutterIconRenderer myGutterIconRenderer;
+ private static final Key<Boolean> EXECUTION_POINT_HIGHLIGHTER_KEY = Key.create("EXECUTION_POINT_HIGHLIGHTER_KEY");
public ExecutionPointHighlighter(final Project project) {
myProject = project;
@@ -151,6 +153,7 @@
EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
myRangeHighlighter = myEditor.getMarkupModel().addLineHighlighter(line, DebuggerColors.EXECUTION_LINE_HIGHLIGHTERLAYER,
scheme.getAttributes(DebuggerColors.EXECUTIONPOINT_ATTRIBUTES));
+ myRangeHighlighter.putUserData(EXECUTION_POINT_HIGHLIGHTER_KEY, true);
myRangeHighlighter.setGutterIconRenderer(myGutterIconRenderer);
}
}
diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java
index a25c49d..a5fc96c 100644
--- a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java
+++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java
@@ -102,9 +102,18 @@
if (!StringUtil.isEmpty(byteCode)) {
component.setText(byteCode, element);
} else {
- PsiClass containingClass = getContainingClass(element);
- PsiFile containingFile = element.getContainingFile();
- component.setText("No bytecode found for " + SymbolPresentationUtil.getSymbolPresentableText(containingClass != null ? containingClass : containingFile));
+ PsiElement presentableElement = getContainingClass(element);
+ if (presentableElement == null) {
+ presentableElement = element.getContainingFile();
+ if (presentableElement == null && element instanceof PsiNamedElement) {
+ presentableElement = element;
+ }
+ if (presentableElement == null) {
+ component.setText("No bytecode found");
+ return;
+ }
+ }
+ component.setText("No bytecode found for " + SymbolPresentationUtil.getSymbolPresentableText(presentableElement));
}
content.setDisplayName(getTitle(element));
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
index b3c238e..44b5be3 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
@@ -3,6 +3,9 @@
<extensions xmlns="com.intellij">
<!--group.names.abstraction.issues-->
+ <localInspection language="JAVA" shortName="BooleanParameter" bundle="com.siyeh.InspectionGadgetsBundle" key="boolean.parameter.display.name"
+ groupBundle="messages.InspectionsBundle" groupKey="group.names.abstraction.issues" enabledByDefault="false"
+ level="WARNING" implementationClass="com.siyeh.ig.abstraction.BooleanParameterInspection"/>
<localInspection language="JAVA" shortName="CastToConcreteClass" bundle="com.siyeh.InspectionGadgetsBundle" key="cast.to.concrete.class.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.abstraction.issues" enabledByDefault="false"
level="WARNING" implementationClass="com.siyeh.ig.abstraction.CastToConcreteClassInspection"/>
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
index 7da4e06..694189a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
@@ -400,15 +400,12 @@
anonymous.class.field.hides.containing.method.variable.problem.descriptor=Anonymous class field <code>#ref</code> hides variable in containing method #loc
anonymous.class.variable.hides.containing.method.variable.problem.descriptor=Anonymous class local variable <code>#ref</code> hides variable in containing method #loc
channel.opened.not.closed.display.name=Channel opened but not safely closed
-channel.opened.not.closed.problem.descriptor=''{0}'' should be opened in front of a ''try'' block and closed in the corresponding ''finally'' block #loc
drivermanager.call.display.name=Use of DriverManager to get JDBC connection
drivermanager.call.problem.descriptor=Call to <code>DriverManager.#ref()</code> #loc
hibernate.resource.opened.not.closed.display.name=Hibernate resource opened but not safely closed
-hibernate.resource.opened.not.closed.problem.descriptor=''{0}'' should be opened in front of a ''try'' block and closed in the corresponding ''finally'' block #loc
i.o.resource.opened.not.closed.display.name=I/O resource opened but not safely closed
resource.opened.not.closed.problem.descriptor=''{0}'' should be opened in front of a ''try'' block and closed in the corresponding ''finally'' block #loc
jdbc.resource.opened.not.closed.display.name=JDBC resource opened but not safely closed
-jdbc.resource.opened.not.closed.problem.descriptor=JDBC ''{0}'' should be opened in front of a ''try'' block and closed in the corresponding ''finally'' block #loc
jndi.resource.opened.not.closed.display.name=JNDI resource opened but not safely closed
socket.opened.not.closed.display.name=Socket opened but not safely closed
annotation.class.display.name=Annotation class
@@ -2033,4 +2030,8 @@
junit.datapoint.problem.descriptor={1}s annotated with @DataPoint should be {0}
inner.class.referenced.via.subclass.display.name=Inner class referenced via subclass
inner.class.referenced.via.subclass.problem.descriptor=Inner class <code>#ref</code> declared in class ''{0}'' but referenced via subclass ''{1}'' #loc
-inner.class.referenced.via.subclass.quickfix=Rationalize inner class access
\ No newline at end of file
+inner.class.referenced.via.subclass.quickfix=Rationalize inner class access
+boolean.parameter.display.name='public' method with 'boolean' parameter
+boolean.parameter.problem.descriptor='public' method <code>#ref</code> with 'boolean' parameter
+boolean.parameters.problem.descriptor='public' method <code>#ref</code> with 'boolean' parameters
+boolean.parameter.only.report.multiple.option=Only report methods with multiple boolean parameters
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/InspectionGadgetsFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/InspectionGadgetsFix.java
index 1aa6827..7cd60f3b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/InspectionGadgetsFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/InspectionGadgetsFix.java
@@ -41,15 +41,6 @@
private boolean myOnTheFly = false;
- /**
- * To appear in "Apply Fix" statement when multiple Quick Fixes exist
- */
- @Override
- @NotNull
- public String getFamilyName() {
- return "";
- }
-
@Override
public final void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement problemElement = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/BooleanParameterInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/BooleanParameterInspection.java
new file mode 100644
index 0000000..5513f42
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/BooleanParameterInspection.java
@@ -0,0 +1,103 @@
+/*
+ * 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.siyeh.ig.abstraction;
+
+import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PropertyUtil;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class BooleanParameterInspection extends BaseInspection {
+
+ @SuppressWarnings("PublicField")
+ public boolean onlyReportMultiple = false;
+
+ @Nls
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return InspectionGadgetsBundle.message("boolean.parameter.display.name");
+ }
+
+ @NotNull
+ @Override
+ protected String buildErrorString(Object... infos) {
+ if (((Integer)infos[0]).intValue() == 1) {
+ return InspectionGadgetsBundle.message("boolean.parameter.problem.descriptor");
+ }
+ else {
+ return InspectionGadgetsBundle.message("boolean.parameters.problem.descriptor");
+ }
+ }
+
+ @Nullable
+ @Override
+ public JComponent createOptionsPanel() {
+ return new SingleCheckboxOptionsPanel(
+ InspectionGadgetsBundle.message("boolean.parameter.only.report.multiple.option"), this, "onlyReportMultiple");
+ }
+
+ @Override
+ public BaseInspectionVisitor buildVisitor() {
+ return new BooleanParameterVisitor();
+ }
+
+ private class BooleanParameterVisitor extends BaseInspectionVisitor {
+
+ @Override
+ public void visitMethod(PsiMethod method) {
+ super.visitMethod(method);
+ if (!method.hasModifierProperty(PsiModifier.PUBLIC)) {
+ final PsiClass aClass = method.getContainingClass();
+ if (aClass == null || !aClass.isInterface()) {
+ return;
+ }
+ }
+ if (PropertyUtil.isSimpleSetter(method)) {
+ return;
+ }
+ final PsiParameterList parameterList = method.getParameterList();
+ final PsiParameter[] parameters = parameterList.getParameters();
+ int count = 0;
+ for (PsiParameter parameter : parameters) {
+ final PsiType type = parameter.getType();
+ if (!PsiPrimitiveType.BOOLEAN.equals(type)) {
+ continue;
+ }
+ count++;
+ if (count > 1) {
+ break;
+ }
+ }
+
+ if (count == 0 || onlyReportMultiple && count == 1) {
+ return;
+ }
+ registerMethodError(method, Integer.valueOf(count));
+ }
+ }
+}
+
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/DeclareCollectionAsInterfaceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/DeclareCollectionAsInterfaceInspection.java
index 53ef3d2..2180e66d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/DeclareCollectionAsInterfaceInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/DeclareCollectionAsInterfaceInspection.java
@@ -108,6 +108,12 @@
"declare.collection.as.interface.quickfix", typeString);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Weaken type";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspection.java
index d0f9349..a312008 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspection.java
@@ -64,6 +64,11 @@
}
private static class OverlyStrongCastFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java
index f036539..a0eede4 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java
@@ -128,6 +128,12 @@
return InspectionGadgetsBundle.message("type.may.be.weakened.quickfix", fqClassName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Weaken type";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
@@ -202,6 +208,9 @@
if (declarationScope instanceof PsiCatchSection) {
// do not weaken catch block parameters
return;
+ } else if (declarationScope instanceof PsiLambdaExpression && parameter.getTypeElement() == null) {
+ //no need to check inferred lambda params
+ return;
}
else if (declarationScope instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)declarationScope;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentUsedAsConditionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentUsedAsConditionInspection.java
index cd4eb42..2081435 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentUsedAsConditionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentUsedAsConditionInspection.java
@@ -51,6 +51,12 @@
return InspectionGadgetsBundle.message("assignment.used.as.condition.replace.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
final PsiAssignmentExpression expression = (PsiAssignmentExpression)descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/IncrementDecrementUsedAsExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/IncrementDecrementUsedAsExpressionInspection.java
index 7b0d4e3..cc40f05 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/IncrementDecrementUsedAsExpressionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/IncrementDecrementUsedAsExpressionInspection.java
@@ -105,6 +105,12 @@
elementText);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Extract to separate statement";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/ReplaceAssignmentWithOperatorAssignmentInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/ReplaceAssignmentWithOperatorAssignmentInspection.java
index e93df55..478164c 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/ReplaceAssignmentWithOperatorAssignmentInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/ReplaceAssignmentWithOperatorAssignmentInspection.java
@@ -136,6 +136,12 @@
signText);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Simplify";
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bitwise/PointlessBitwiseExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bitwise/PointlessBitwiseExpressionInspection.java
index f893ac2..38bafe6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bitwise/PointlessBitwiseExpressionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bitwise/PointlessBitwiseExpressionInspection.java
@@ -175,6 +175,11 @@
return InspectionGadgetsBundle.message(
"pointless.bitwise.expression.simplify.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bitwise/ShiftOutOfRangeInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bitwise/ShiftOutOfRangeInspection.java
index eee9459..e7a224f 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bitwise/ShiftOutOfRangeInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bitwise/ShiftOutOfRangeInspection.java
@@ -87,6 +87,12 @@
Integer.valueOf(value), Integer.valueOf(newValue));
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Fix shift value";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArchaicSystemPropertyAccessInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArchaicSystemPropertyAccessInspection.java
index 430e2ee..3346fdb 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArchaicSystemPropertyAccessInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArchaicSystemPropertyAccessInspection.java
@@ -69,6 +69,11 @@
}
private static class ReplaceWithParseMethodFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
@@ -114,6 +119,12 @@
"archaic.system.property.accessors.replace.standard.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArrayEqualityInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArrayEqualityInspection.java
index 540354d..ae477e5 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArrayEqualityInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArrayEqualityInspection.java
@@ -75,6 +75,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace with implicit equals";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArrayEqualsInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArrayEqualsInspection.java
index 0eee77f..ae607f1 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArrayEqualsInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArrayEqualsInspection.java
@@ -81,6 +81,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace with Arrays.equals";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArrayHashCodeInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArrayHashCodeInspection.java
index 2e46a81..d5a3b68 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArrayHashCodeInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ArrayHashCodeInspection.java
@@ -79,6 +79,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace with implicit 'hashCode'";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspection.java
index 77fd142..832cb68 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspection.java
@@ -214,6 +214,12 @@
return InspectionGadgetsBundle.message("cast.conflicts.with.instanceof.quickfix1", myCastType, myInstanceofType);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace cast type";
+ }
+
@Override
protected PsiElement replace(PsiTypeElement castTypeElement, PsiTypeElement instanceofTypeElement) {
return castTypeElement.replace(instanceofTypeElement);
@@ -230,6 +236,12 @@
myCastType = castType;
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace instanceOf type";
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ClassNewInstanceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ClassNewInstanceInspection.java
index afca4c1..55c5da3 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ClassNewInstanceInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ClassNewInstanceInspection.java
@@ -64,6 +64,12 @@
"class.new.instance.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyInitializerInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyInitializerInspection.java
index 4a3976d..1cbc998 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyInitializerInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyInitializerInspection.java
@@ -56,6 +56,11 @@
}
private static class EmptyInitializerFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ImplicitArrayToStringInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ImplicitArrayToStringInspection.java
index 84307f7..20649cf 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ImplicitArrayToStringInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ImplicitArrayToStringInspection.java
@@ -86,6 +86,12 @@
this.removeToString = removeToString;
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Make Array.toString() implicit";
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/InnerClassReferencedViaSubclassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/InnerClassReferencedViaSubclassInspection.java
index 0270384..36eac11 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/InnerClassReferencedViaSubclassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/InnerClassReferencedViaSubclassInspection.java
@@ -60,6 +60,11 @@
public String getName() {
return InspectionGadgetsBundle.message("inner.class.referenced.via.subclass.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MathRandomCastToIntInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MathRandomCastToIntInspection.java
index b21554f..f3af8bd 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MathRandomCastToIntInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MathRandomCastToIntInspection.java
@@ -65,6 +65,11 @@
private static class MathRandomCastToIntegerFix extends InspectionGadgetsFix {
@Override
@NotNull
+ public String getFamilyName() {
+ return getName();
+ }
+ @Override
+ @NotNull
public String getName() {
return InspectionGadgetsBundle.message(
"math.random.cast.to.int.quickfix");
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NewStringBufferWithCharArgumentInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NewStringBufferWithCharArgumentInspection.java
index f72d9d5..0532b9c 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NewStringBufferWithCharArgumentInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NewStringBufferWithCharArgumentInspection.java
@@ -62,6 +62,11 @@
private static class NewStringBufferWithCharArgumentFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NonShortCircuitBooleanInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NonShortCircuitBooleanInspection.java
index cf34693..b7a765d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NonShortCircuitBooleanInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NonShortCircuitBooleanInspection.java
@@ -63,6 +63,12 @@
return InspectionGadgetsBundle.message("non.short.circuit.boolean.expression.replace.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiPolyadicExpression expression = (PsiPolyadicExpression)descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StaticCallOnSubclassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StaticCallOnSubclassInspection.java
index 77bc67c..65a1f8e 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StaticCallOnSubclassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StaticCallOnSubclassInspection.java
@@ -64,6 +64,11 @@
return InspectionGadgetsBundle.message(
"static.method.via.subclass.rationalize.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StaticFieldReferenceOnSubclassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StaticFieldReferenceOnSubclassInspection.java
index feffc6e..b80bc1d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StaticFieldReferenceOnSubclassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StaticFieldReferenceOnSubclassInspection.java
@@ -59,6 +59,11 @@
}
private static class StaticFieldOnSubclassFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringConcatenationInFormatCallInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringConcatenationInFormatCallInspection.java
index 812b105..2331526 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringConcatenationInFormatCallInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringConcatenationInFormatCallInspection.java
@@ -68,6 +68,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return InspectionGadgetsBundle.message("string.concatenation.in.format.call.plural.quickfix");
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement().getParent().getParent();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringConcatenationInMessageFormatCallInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringConcatenationInMessageFormatCallInspection.java
index 0ba3920..67448d5 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringConcatenationInMessageFormatCallInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringConcatenationInMessageFormatCallInspection.java
@@ -67,6 +67,12 @@
return InspectionGadgetsBundle.message("string.concatenation.in.format.call.quickfix", variableName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace concatenation with argument";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/UseOfPropertiesAsHashtableInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/UseOfPropertiesAsHashtableInspection.java
index 4d6dae4..4fa34c6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/UseOfPropertiesAsHashtableInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/UseOfPropertiesAsHashtableInspection.java
@@ -90,6 +90,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Fix property access";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassMayBeInterfaceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassMayBeInterfaceInspection.java
index 083e39f..1788bfa 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassMayBeInterfaceInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassMayBeInterfaceInspection.java
@@ -58,6 +58,11 @@
public String getName() {
return InspectionGadgetsBundle.message("class.may.be.interface.convert.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected boolean prepareForWriting() {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ListenerMayUseAdapterInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ListenerMayUseAdapterInspection.java
index 96aed1e..dff210f 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ListenerMayUseAdapterInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ListenerMayUseAdapterInspection.java
@@ -84,6 +84,12 @@
adapterClass.getName());
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace with adapter";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/MissingDeprecatedAnnotationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/MissingDeprecatedAnnotationInspection.java
index 92c3d133..ec87f2a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/MissingDeprecatedAnnotationInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/MissingDeprecatedAnnotationInspection.java
@@ -59,6 +59,12 @@
return InspectionGadgetsBundle.message("missing.deprecated.annotation.add.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement identifier = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/MissingOverrideAnnotationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/MissingOverrideAnnotationInspection.java
index 0e1c587..3c18cc3 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/MissingOverrideAnnotationInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/MissingOverrideAnnotationInspection.java
@@ -89,6 +89,11 @@
return InspectionGadgetsBundle.message(
"missing.override.annotation.add.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/PublicConstructorInNonPublicClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/PublicConstructorInNonPublicClassInspection.java
index 7cf7cc5..ec357ae 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/PublicConstructorInNonPublicClassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/PublicConstructorInNonPublicClassInspection.java
@@ -72,6 +72,12 @@
this.modifier = modifier;
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Fix constructor modifier";
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/UtilityClassWithPublicConstructorInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/UtilityClassWithPublicConstructorInspection.java
index 59d529e..273c944 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/UtilityClassWithPublicConstructorInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/UtilityClassWithPublicConstructorInspection.java
@@ -73,6 +73,12 @@
Integer.valueOf(m_multipleConstructors ? 1 : 2));
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Make constructors private";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/cloneable/CloneDeclaresCloneNotSupportedInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/cloneable/CloneDeclaresCloneNotSupportedInspection.java
index 040ac91..4708776 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/cloneable/CloneDeclaresCloneNotSupportedInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/cloneable/CloneDeclaresCloneNotSupportedInspection.java
@@ -67,6 +67,11 @@
public String getName() {
return InspectionGadgetsBundle.message("clone.doesnt.declare.clonenotsupportedexception.declare.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/cloneable/CloneableImplementsCloneInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/cloneable/CloneableImplementsCloneInspection.java
index 31552bb..6213c82 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/cloneable/CloneableImplementsCloneInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/cloneable/CloneableImplementsCloneInspection.java
@@ -71,6 +71,11 @@
public String getName() {
return InspectionGadgetsBundle.message("cloneable.class.without.clone.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConditionalExpressionWithIdenticalBranchesInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConditionalExpressionWithIdenticalBranchesInspection.java
index d51b23e..beb27e4 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConditionalExpressionWithIdenticalBranchesInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConditionalExpressionWithIdenticalBranchesInspection.java
@@ -57,6 +57,11 @@
return InspectionGadgetsBundle.message(
"conditional.expression.with.identical.branches.collapse.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConfusingElseInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConfusingElseInspection.java
index 975a421..11062a3 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConfusingElseInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConfusingElseInspection.java
@@ -71,6 +71,11 @@
}
private static class ConfusingElseFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConstantConditionalExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConstantConditionalExpressionInspection.java
index 12bf1ce..abb3fb9 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConstantConditionalExpressionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConstantConditionalExpressionInspection.java
@@ -81,6 +81,12 @@
"constant.conditional.expression.simplify.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConstantIfStatementInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConstantIfStatementInspection.java
index c3b87fe6..1afa566 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConstantIfStatementInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ConstantIfStatementInspection.java
@@ -64,6 +64,11 @@
}
private static class ConstantIfStatementFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/DoubleNegationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/DoubleNegationInspection.java
index 92eebc3..c503eac 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/DoubleNegationInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/DoubleNegationInspection.java
@@ -60,6 +60,11 @@
public String getName() {
return InspectionGadgetsBundle.message("double.negation.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/FallthruInSwitchStatementInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/FallthruInSwitchStatementInspection.java
index b82a755f..10f7984 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/FallthruInSwitchStatementInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/FallthruInSwitchStatementInspection.java
@@ -61,6 +61,11 @@
}
private static class FallthruInSwitchStatementFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ForLoopReplaceableByWhileInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ForLoopReplaceableByWhileInspection.java
index 3817162..2b1ff6b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ForLoopReplaceableByWhileInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ForLoopReplaceableByWhileInspection.java
@@ -77,6 +77,12 @@
"for.loop.replaceable.by.while.replace.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ForLoopWithMissingComponentInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ForLoopWithMissingComponentInspection.java
index d764cc3..b31da17 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ForLoopWithMissingComponentInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/ForLoopWithMissingComponentInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,11 +17,11 @@
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.psi.*;
-import com.intellij.psi.util.InheritanceUtil;
import com.siyeh.HardcodedMethodConstants;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -29,16 +29,13 @@
public class ForLoopWithMissingComponentInspection extends BaseInspection {
- /**
- * @noinspection PublicField
- */
+ @SuppressWarnings("PublicField")
public boolean ignoreCollectionLoops = false;
@Override
@NotNull
public String getDisplayName() {
- return InspectionGadgetsBundle.message(
- "for.loop.with.missing.component.display.name");
+ return InspectionGadgetsBundle.message("for.loop.with.missing.component.display.name");
}
@Override
@@ -49,43 +46,35 @@
final boolean hasUpdate = ((Boolean)infos[2]).booleanValue();
if (hasInitializer) {
if (hasCondition) {
- return InspectionGadgetsBundle.message(
- "for.loop.with.missing.component.problem.descriptor3");
+ return InspectionGadgetsBundle.message("for.loop.with.missing.component.problem.descriptor3");
}
else if (hasUpdate) {
- return InspectionGadgetsBundle.message(
- "for.loop.with.missing.component.problem.descriptor2");
+ return InspectionGadgetsBundle.message("for.loop.with.missing.component.problem.descriptor2");
}
else {
- return InspectionGadgetsBundle.message(
- "for.loop.with.missing.component.problem.descriptor6");
+ return InspectionGadgetsBundle.message("for.loop.with.missing.component.problem.descriptor6");
}
}
else if (hasCondition) {
if (hasUpdate) {
- return InspectionGadgetsBundle.message(
- "for.loop.with.missing.component.problem.descriptor1");
+ return InspectionGadgetsBundle.message("for.loop.with.missing.component.problem.descriptor1");
}
else {
- return InspectionGadgetsBundle.message(
- "for.loop.with.missing.component.problem.descriptor5");
+ return InspectionGadgetsBundle.message("for.loop.with.missing.component.problem.descriptor5");
}
}
else if (hasUpdate) {
- return InspectionGadgetsBundle.message(
- "for.loop.with.missing.component.problem.descriptor4");
+ return InspectionGadgetsBundle.message("for.loop.with.missing.component.problem.descriptor4");
}
else {
- return InspectionGadgetsBundle.message(
- "for.loop.with.missing.component.problem.descriptor7");
+ return InspectionGadgetsBundle.message("for.loop.with.missing.component.problem.descriptor7");
}
}
@Override
@Nullable
public JComponent createOptionsPanel() {
- return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message(
- "for.loop.with.missing.component.collection.loop.option"),
+ return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("for.loop.with.missing.component.collection.loop.option"),
this, "ignoreCollectionLoops");
}
@@ -94,12 +83,10 @@
return new ForLoopWithMissingComponentVisitor();
}
- private class ForLoopWithMissingComponentVisitor
- extends BaseInspectionVisitor {
+ private class ForLoopWithMissingComponentVisitor extends BaseInspectionVisitor {
@Override
- public void visitForStatement(
- @NotNull PsiForStatement statement) {
+ public void visitForStatement(@NotNull PsiForStatement statement) {
super.visitForStatement(statement);
final boolean hasCondition = hasCondition(statement);
final boolean hasInitializer = hasInitializer(statement);
@@ -110,8 +97,7 @@
if (ignoreCollectionLoops && isCollectionLoopStatement(statement)) {
return;
}
- registerStatementError(statement, Boolean.valueOf(hasInitializer),
- Boolean.valueOf(hasCondition), Boolean.valueOf(hasUpdate));
+ registerStatementError(statement, Boolean.valueOf(hasInitializer), Boolean.valueOf(hasCondition), Boolean.valueOf(hasUpdate));
}
private boolean hasCondition(PsiForStatement statement) {
@@ -120,8 +106,7 @@
private boolean hasInitializer(PsiForStatement statement) {
final PsiStatement initialization = statement.getInitialization();
- return initialization != null &&
- !(initialization instanceof PsiEmptyStatement);
+ return initialization != null && !(initialization instanceof PsiEmptyStatement);
}
private boolean hasUpdate(PsiForStatement statement) {
@@ -130,47 +115,18 @@
}
private boolean isCollectionLoopStatement(PsiForStatement forStatement) {
- final PsiStatement initialization =
- forStatement.getInitialization();
+ final PsiStatement initialization = forStatement.getInitialization();
if (!(initialization instanceof PsiDeclarationStatement)) {
return false;
}
- final PsiDeclarationStatement declaration =
- (PsiDeclarationStatement)initialization;
- final PsiElement[] declaredElements =
- declaration.getDeclaredElements();
+ final PsiDeclarationStatement declaration = (PsiDeclarationStatement)initialization;
+ final PsiElement[] declaredElements = declaration.getDeclaredElements();
for (PsiElement declaredElement : declaredElements) {
if (!(declaredElement instanceof PsiVariable)) {
continue;
}
final PsiVariable variable = (PsiVariable)declaredElement;
- final PsiType variableType = variable.getType();
- if (!(variableType instanceof PsiClassType)) {
- continue;
- }
- final PsiClassType classType = (PsiClassType)variableType;
- final PsiClass declaredClass = classType.resolve();
- if (declaredClass == null) {
- continue;
- }
- if (!InheritanceUtil.isInheritor(declaredClass,
- CommonClassNames.JAVA_UTIL_ITERATOR)) {
- continue;
- }
- final PsiExpression initialValue = variable.getInitializer();
- if (initialValue == null) {
- continue;
- }
- if (!(initialValue instanceof PsiMethodCallExpression)) {
- continue;
- }
- final PsiMethodCallExpression initialCall =
- (PsiMethodCallExpression)initialValue;
- final PsiReferenceExpression initialMethodExpression =
- initialCall.getMethodExpression();
- final String initialCallName =
- initialMethodExpression.getReferenceName();
- if (!HardcodedMethodConstants.ITERATOR.equals(initialCallName)) {
+ if (!TypeUtils.variableHasTypeOrSubtype(variable, CommonClassNames.JAVA_UTIL_ITERATOR)) {
continue;
}
final PsiExpression condition = forStatement.getCondition();
@@ -181,11 +137,9 @@
return false;
}
- private boolean isHasNext(PsiExpression condition,
- PsiVariable iterator) {
+ private boolean isHasNext(PsiExpression condition, PsiVariable iterator) {
if (condition instanceof PsiBinaryExpression) {
- final PsiBinaryExpression binaryExpression =
- (PsiBinaryExpression)condition;
+ final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)condition;
final PsiExpression lhs = binaryExpression.getLOperand();
final PsiExpression rhs = binaryExpression.getROperand();
return isHasNext(lhs, iterator) || isHasNext(rhs, iterator);
@@ -193,26 +147,22 @@
if (!(condition instanceof PsiMethodCallExpression)) {
return false;
}
- final PsiMethodCallExpression call =
- (PsiMethodCallExpression)condition;
+ final PsiMethodCallExpression call = (PsiMethodCallExpression)condition;
final PsiExpressionList argumentList = call.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length != 0) {
return false;
}
- final PsiReferenceExpression methodExpression =
- call.getMethodExpression();
+ final PsiReferenceExpression methodExpression = call.getMethodExpression();
final String methodName = methodExpression.getReferenceName();
if (!HardcodedMethodConstants.HAS_NEXT.equals(methodName)) {
return false;
}
- final PsiExpression qualifier =
- methodExpression.getQualifierExpression();
+ final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (!(qualifier instanceof PsiReferenceExpression)) {
return true;
}
- final PsiReferenceExpression referenceExpression =
- (PsiReferenceExpression)qualifier;
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)qualifier;
final PsiElement target = referenceExpression.resolve();
return iterator.equals(target);
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/IfMayBeConditionalInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/IfMayBeConditionalInspection.java
index f06b437..46eb89e 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/IfMayBeConditionalInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/IfMayBeConditionalInspection.java
@@ -74,6 +74,12 @@
"if.may.be.conditional.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/IfStatementWithIdenticalBranchesInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/IfStatementWithIdenticalBranchesInspection.java
index d8b2cdf..6cc7a98 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/IfStatementWithIdenticalBranchesInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/IfStatementWithIdenticalBranchesInspection.java
@@ -69,6 +69,12 @@
"if.statement.with.identical.branches.collapse.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(@NotNull Project project,
ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/LoopWithImplicitTerminationConditionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/LoopWithImplicitTerminationConditionInspection.java
index 95eaca0..cda6605 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/LoopWithImplicitTerminationConditionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/LoopWithImplicitTerminationConditionInspection.java
@@ -58,6 +58,11 @@
private static class LoopWithImplicitTerminationConditionFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/NegatedConditionalInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/NegatedConditionalInspection.java
index e0d905c..b8fee88 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/NegatedConditionalInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/NegatedConditionalInspection.java
@@ -76,6 +76,11 @@
}
private static class NegatedConditionalFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/NegatedEqualityExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/NegatedEqualityExpressionInspection.java
index c7caa05..d7dfbd6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/NegatedEqualityExpressionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/NegatedEqualityExpressionInspection.java
@@ -57,6 +57,12 @@
return InspectionGadgetsBundle.message("negated.equality.expression.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/NegatedIfElseInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/NegatedIfElseInspection.java
index 22ca6da..289c74c 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/NegatedIfElseInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/NegatedIfElseInspection.java
@@ -76,6 +76,12 @@
private static class NegatedIfElseFix extends InspectionGadgetsFix {
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/PointlessBooleanExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/PointlessBooleanExpressionInspection.java
index dd14773..917abf2 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/PointlessBooleanExpressionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/PointlessBooleanExpressionInspection.java
@@ -271,6 +271,11 @@
}
private class PointlessBooleanExpressionFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/PointlessNullCheckInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/PointlessNullCheckInspection.java
index 1500f27..a958a67 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/PointlessNullCheckInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/PointlessNullCheckInspection.java
@@ -80,6 +80,12 @@
return InspectionGadgetsBundle.message("pointless.nullcheck.simplify.quickfix", myExpressionText);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Simplify";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/SimplifiableConditionalExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/SimplifiableConditionalExpressionInspection.java
index 6b1a1e3..9263063 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/SimplifiableConditionalExpressionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/SimplifiableConditionalExpressionInspection.java
@@ -70,6 +70,12 @@
"constant.conditional.expression.simplify.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/SimplifiableEqualsExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/SimplifiableEqualsExpressionInspection.java
index 5469e57..f93948f 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/SimplifiableEqualsExpressionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/SimplifiableEqualsExpressionInspection.java
@@ -65,6 +65,12 @@
return InspectionGadgetsBundle.message("simplifiable.equals.expression.quickfix", myMethodName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Simplify";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/TrivialIfInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/TrivialIfInspection.java
index 02df887..0a88a12 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/TrivialIfInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/TrivialIfInspection.java
@@ -65,6 +65,11 @@
private static class TrivialIfFix extends InspectionGadgetsFix {
@Override
@NotNull
+ public String getFamilyName() {
+ return getName();
+ }
+ @Override
+ @NotNull
public String getName() {
return InspectionGadgetsBundle.message(
"constant.conditional.expression.simplify.quickfix");
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryConditionalExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryConditionalExpressionInspection.java
index d7b654c..446e713 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryConditionalExpressionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryConditionalExpressionInspection.java
@@ -85,6 +85,11 @@
private static class UnnecessaryConditionalFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryLabelOnBreakStatementInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryLabelOnBreakStatementInspection.java
index 3f662822..4d3bca4 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryLabelOnBreakStatementInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryLabelOnBreakStatementInspection.java
@@ -55,6 +55,11 @@
private static class UnnecessaryLabelOnBreakStatementFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryLabelOnContinueStatementInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryLabelOnContinueStatementInspection.java
index 8dfbef3..4c422d1 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryLabelOnContinueStatementInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryLabelOnContinueStatementInspection.java
@@ -55,6 +55,11 @@
private static class UnnecessaryLabelOnContinueStatementFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/ConstantValueVariableUseInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/ConstantValueVariableUseInspection.java
index 8fbb831..3cd34b1 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/ConstantValueVariableUseInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/ConstantValueVariableUseInspection.java
@@ -71,6 +71,12 @@
myText);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Simplify";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/OrredNotEqualExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/OrredNotEqualExpressionInspection.java
index 204e624..0ae7803 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/OrredNotEqualExpressionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/OrredNotEqualExpressionInspection.java
@@ -58,6 +58,11 @@
private static class OrredNotEqualExpressionFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/encapsulation/ReturnOfDateFieldInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/encapsulation/ReturnOfDateFieldInspection.java
index 1b28605..786236f 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/encapsulation/ReturnOfDateFieldInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/encapsulation/ReturnOfDateFieldInspection.java
@@ -75,6 +75,12 @@
return InspectionGadgetsBundle.message("return.date.calendar.field.quickfix", myType);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Return clone";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/CaughtExceptionImmediatelyRethrownInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/CaughtExceptionImmediatelyRethrownInspection.java
index 3988f48..58a1164 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/CaughtExceptionImmediatelyRethrownInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/CaughtExceptionImmediatelyRethrownInspection.java
@@ -85,6 +85,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Delete catch statement";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java
index 207e5e7..4a9b58b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java
@@ -80,6 +80,11 @@
}
private static class EmptyCatchBlockFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java
index 41ed575..8e3fbeb 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java
@@ -60,6 +60,11 @@
private static class RemoveTryFinallyBlockFix extends InspectionGadgetsFix {
@Override
@NotNull
+ public String getFamilyName() {
+ return getName();
+ }
+ @Override
+ @NotNull
public String getName() {
return InspectionGadgetsBundle.message("remove.try.finally.block.quickfix");
}
@@ -100,7 +105,12 @@
}
private static class RemoveFinallyBlockFix extends InspectionGadgetsFix {
- @Override
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
+ @Override
@NotNull
public String getName() {
return InspectionGadgetsBundle.message("remove.finally.block.quickfix");
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/NullThrownInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/NullThrownInspection.java
index f2cbb1c..c7be176 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/NullThrownInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/NullThrownInspection.java
@@ -49,6 +49,11 @@
}
private static class ThrowNullFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@NotNull
@Override
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/TooBroadThrowsInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/TooBroadThrowsInspection.java
index f080376..338992a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/TooBroadThrowsInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/TooBroadThrowsInspection.java
@@ -124,6 +124,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Fix 'throws' clause";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/finalization/FinalizeNotProtectedInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/finalization/FinalizeNotProtectedInspection.java
index c124c0f..e999566 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/finalization/FinalizeNotProtectedInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/finalization/FinalizeNotProtectedInspection.java
@@ -53,6 +53,11 @@
}
private static class ProtectedFinalizeFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/AddSerialVersionUIDFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/AddSerialVersionUIDFix.java
index fc3d228..e207bb6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/AddSerialVersionUIDFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/AddSerialVersionUIDFix.java
@@ -31,6 +31,12 @@
return InspectionGadgetsBundle.message("add.serialversionuidfield.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/AddThisQualifierFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/AddThisQualifierFix.java
index c3600bf..b649973 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/AddThisQualifierFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/AddThisQualifierFix.java
@@ -30,6 +30,11 @@
import org.jetbrains.annotations.NotNull;
public class AddThisQualifierFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ChangeModifierFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ChangeModifierFix.java
index 80f932d..2be78a4 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ChangeModifierFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ChangeModifierFix.java
@@ -43,6 +43,12 @@
modifierText);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Change modifier";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/DeleteImportFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/DeleteImportFix.java
index 21188c6..5499466 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/DeleteImportFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/DeleteImportFix.java
@@ -30,6 +30,12 @@
return InspectionGadgetsBundle.message("delete.import.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/DeleteUnnecessaryStatementFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/DeleteUnnecessaryStatementFix.java
index ccd70d6..d76a992 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/DeleteUnnecessaryStatementFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/DeleteUnnecessaryStatementFix.java
@@ -40,6 +40,12 @@
"smth.unnecessary.remove.quickfix", name);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Remove redundant statement";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/EqualityToEqualsFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/EqualityToEqualsFix.java
index 4ef8fea..7ab4204 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/EqualityToEqualsFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/EqualityToEqualsFix.java
@@ -30,6 +30,11 @@
import org.jetbrains.annotations.NotNull;
public class EqualityToEqualsFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java
index e301dd0..9ef4c14 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java
@@ -39,6 +39,12 @@
"extract.parameter.as.local.variable.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeCloneableFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeCloneableFix.java
index 1d76d41..d78a3cd9 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeCloneableFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeCloneableFix.java
@@ -46,6 +46,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Make 'Cloneable'";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeFieldFinalFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeFieldFinalFix.java
index 9afcac8..80ebfa0 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeFieldFinalFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeFieldFinalFix.java
@@ -54,6 +54,12 @@
fieldName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Make final";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeFieldStaticFinalFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeFieldStaticFinalFix.java
index 36d168d..c0d5a8a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeFieldStaticFinalFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeFieldStaticFinalFix.java
@@ -58,6 +58,12 @@
"make.static.final.quickfix", fieldName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Make static final";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeInitializerExplicitFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeInitializerExplicitFix.java
index 6b64b81..67dc8f5 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeInitializerExplicitFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeInitializerExplicitFix.java
@@ -32,6 +32,11 @@
return InspectionGadgetsBundle.message(
"make.initialization.explicit.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeSerializableFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeSerializableFix.java
index a0a781a..24d0f62 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeSerializableFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/MakeSerializableFix.java
@@ -34,6 +34,12 @@
"make.class.serializable.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/NormalizeDeclarationFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/NormalizeDeclarationFix.java
index f4fabe4..b2a24d7 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/NormalizeDeclarationFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/NormalizeDeclarationFix.java
@@ -24,6 +24,11 @@
import org.jetbrains.annotations.NotNull;
public class NormalizeDeclarationFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/RemoveModifierFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/RemoveModifierFix.java
index de6a2c4..65660aa 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/RemoveModifierFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/RemoveModifierFix.java
@@ -31,6 +31,12 @@
this.modifierText = modifierText;
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Remove modifier";
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/AbstractMethodOverridesAbstractMethodInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/AbstractMethodOverridesAbstractMethodInspection.java
index 0a0f981..c35c36d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/AbstractMethodOverridesAbstractMethodInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/AbstractMethodOverridesAbstractMethodInspection.java
@@ -77,6 +77,12 @@
return InspectionGadgetsBundle.message("abstract.method.overrides.abstract.method.remove.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement methodNameIdentifier = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/RedundantMethodOverrideInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/RedundantMethodOverrideInspection.java
index 8fb2549..46ef38b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/RedundantMethodOverrideInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/RedundantMethodOverrideInspection.java
@@ -54,6 +54,11 @@
private static class RedundantMethodOverrideFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspection.java
index 6c01383..dda5dac 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspection.java
@@ -59,6 +59,11 @@
}
private static class TypeParameterExtendsFinalClassFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/NonThreadSafeLazyInitializationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/NonThreadSafeLazyInitializationInspection.java
index cf30a6d..2e0beba 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/NonThreadSafeLazyInitializationInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/NonThreadSafeLazyInitializationInspection.java
@@ -236,5 +236,11 @@
public String getName() {
return "Introduce holder class";
}
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
}
}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/internationalization/AbsoluteAlignmentInUserInterfaceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/internationalization/AbsoluteAlignmentInUserInterfaceInspection.java
index bf6286f..9340ff4 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/internationalization/AbsoluteAlignmentInUserInterfaceInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/internationalization/AbsoluteAlignmentInUserInterfaceInspection.java
@@ -101,6 +101,12 @@
return InspectionGadgetsBundle.message("absolute.alignment.in.user.interface.quickfix", shortClassName, myReplacement);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace with constant";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/MultiplyOrDivideByPowerOfTwoInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/MultiplyOrDivideByPowerOfTwoInspection.java
index 53adeb8..d25349c 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/MultiplyOrDivideByPowerOfTwoInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/MultiplyOrDivideByPowerOfTwoInspection.java
@@ -146,6 +146,11 @@
return InspectionGadgetsBundle.message(
"multiply.or.divide.by.power.of.two.replace.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java
index da42176..bc1fbe0 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java
@@ -96,6 +96,12 @@
elementName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Make package-local";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/SimplifiableIfStatementInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/SimplifiableIfStatementInspection.java
index 3946a0b..57d30db 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/SimplifiableIfStatementInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/SimplifiableIfStatementInspection.java
@@ -264,6 +264,11 @@
}
private static class SimplifiableIfStatementFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/SingleCharacterStartsWithInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/SingleCharacterStartsWithInspection.java
index 68f623b..c319ff3 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/SingleCharacterStartsWithInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/SingleCharacterStartsWithInspection.java
@@ -53,6 +53,11 @@
private static class SingleCharacterStartsWithFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java
index c7c734b..2aa3c07 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java
@@ -58,6 +58,12 @@
"class.without.constructor.create.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/HtmlTagCanBeJavadocTagInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/HtmlTagCanBeJavadocTagInspection.java
index 2613826..f8dace6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/HtmlTagCanBeJavadocTagInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/HtmlTagCanBeJavadocTagInspection.java
@@ -70,6 +70,11 @@
return InspectionGadgetsBundle.message(
"html.tag.can.be.javadoc.tag.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/UnnecessaryInheritDocInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/UnnecessaryInheritDocInspection.java
index c1f05d7..780a44b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/UnnecessaryInheritDocInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/UnnecessaryInheritDocInspection.java
@@ -65,6 +65,11 @@
return InspectionGadgetsBundle.message(
"unnecessary.inherit.doc.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/UnnecessaryJavaDocLinkInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/UnnecessaryJavaDocLinkInspection.java
index 63b1d75..554deb5 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/UnnecessaryJavaDocLinkInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/UnnecessaryJavaDocLinkInspection.java
@@ -99,6 +99,12 @@
"unnecessary.javadoc.link.quickfix", tagName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Remove redundant tag";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/AutoBoxingInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/AutoBoxingInspection.java
index 798d53e..292d106 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/AutoBoxingInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/AutoBoxingInspection.java
@@ -108,6 +108,12 @@
return InspectionGadgetsBundle.message("auto.boxing.make.boxing.explicit.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
final PsiExpression expression = (PsiExpression)descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/AutoUnboxingInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/AutoUnboxingInspection.java
index 0befc94..fa83ad8 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/AutoUnboxingInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/AutoUnboxingInspection.java
@@ -121,6 +121,11 @@
public String getName() {
return InspectionGadgetsBundle.message("auto.unboxing.make.unboxing.explicit.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/ForeachStatementInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/ForeachStatementInspection.java
index e394370..f0b1e40 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/ForeachStatementInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/ForeachStatementInspection.java
@@ -50,6 +50,11 @@
}
private static class ForEachFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/VarargParameterInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/VarargParameterInspection.java
index 07f12b2..6b03778 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/VarargParameterInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/VarargParameterInspection.java
@@ -67,6 +67,12 @@
return InspectionGadgetsBundle.message("variable.argument.method.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsCalledOnArrayInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsCalledOnArrayInspection.java
index 30608ed..8670e0a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsCalledOnArrayInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsCalledOnArrayInspection.java
@@ -56,6 +56,12 @@
return InspectionGadgetsBundle.message("assertequals.called.on.arrays.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement methodNameIdentifier = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsMayBeAssertSameInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsMayBeAssertSameInspection.java
index 82ac660..8fae6b0 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsMayBeAssertSameInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/AssertEqualsMayBeAssertSameInspection.java
@@ -54,6 +54,12 @@
return InspectionGadgetsBundle.message("assertequals.may.be.assertsame.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/MakePublicStaticFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/MakePublicStaticFix.java
index 7e8a6c2..0e54556 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/MakePublicStaticFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/MakePublicStaticFix.java
@@ -3,7 +3,6 @@
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiField;
import com.intellij.psi.PsiMember;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.util.PsiUtil;
@@ -41,4 +40,10 @@
public String getName() {
return myName;
}
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Make public/static";
+ }
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/MisorderedAssertEqualsParametersInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/MisorderedAssertEqualsParametersInspection.java
index 49a9bed..edf499d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/MisorderedAssertEqualsParametersInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/MisorderedAssertEqualsParametersInspection.java
@@ -55,6 +55,11 @@
}
private static class FlipParametersFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/MultipleExceptionsDeclaredOnTestMethodInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/MultipleExceptionsDeclaredOnTestMethodInspection.java
index e92b0c8..185025c 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/MultipleExceptionsDeclaredOnTestMethodInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/MultipleExceptionsDeclaredOnTestMethodInspection.java
@@ -63,6 +63,12 @@
"multiple.exceptions.declared.on.test.method.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/SetupCallsSuperSetupInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/SetupCallsSuperSetupInspection.java
index fafab66..5e0d2ff 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/SetupCallsSuperSetupInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/SetupCallsSuperSetupInspection.java
@@ -51,6 +51,11 @@
}
private static class AddSuperSetUpCall extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/SimplifiableJUnitAssertionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/SimplifiableJUnitAssertionInspection.java
index 72080f7..e5512ae 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/SimplifiableJUnitAssertionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/SimplifiableJUnitAssertionInspection.java
@@ -55,6 +55,12 @@
return InspectionGadgetsBundle.message("simplify.junit.assertion.simplify.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement methodNameIdentifier = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/TeardownCallsSuperTeardownInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/TeardownCallsSuperTeardownInspection.java
index c521c99..4d2230e 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/TeardownCallsSuperTeardownInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/TeardownCallsSuperTeardownInspection.java
@@ -63,6 +63,11 @@
return InspectionGadgetsBundle.message(
"teardown.calls.super.teardown.add.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/BigDecimalEqualsInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/BigDecimalEqualsInspection.java
index 253b5803..ca0d990 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/BigDecimalEqualsInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/BigDecimalEqualsInspection.java
@@ -52,6 +52,11 @@
public String getName() {
return InspectionGadgetsBundle.message("big.decimal.equals.replace.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/CachedNumberConstructorCallInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/CachedNumberConstructorCallInspection.java
index 355a086..803e89c 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/CachedNumberConstructorCallInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/CachedNumberConstructorCallInspection.java
@@ -87,6 +87,12 @@
"cached.number.constructor.call.quickfix", className);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace with '.valueOf' call";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/CharUsedInArithmeticContextInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/CharUsedInArithmeticContextInspection.java
index 0ff6016..5b9a4c4 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/CharUsedInArithmeticContextInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/CharUsedInArithmeticContextInspection.java
@@ -78,6 +78,11 @@
}
private static class CharUsedInArithmeticContentFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
@@ -115,6 +120,12 @@
return InspectionGadgetsBundle.message("char.used.in.arithmetic.context.cast.quickfix", typeText);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Insert cast";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ComparisonToNaNInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ComparisonToNaNInspection.java
index 33b67a8..6ea0bf6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ComparisonToNaNInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ComparisonToNaNInspection.java
@@ -61,6 +61,11 @@
}
private static class ComparisonToNaNFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConfusingFloatingPointLiteralInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConfusingFloatingPointLiteralInspection.java
index 7cc2729..4b08dd9 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConfusingFloatingPointLiteralInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConfusingFloatingPointLiteralInspection.java
@@ -52,6 +52,11 @@
private static class ConfusingFloatingPointLiteralFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConstantMathCallInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConstantMathCallInspection.java
index f94adeb..71b6a97 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConstantMathCallInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConstantMathCallInspection.java
@@ -83,6 +83,11 @@
}
private static class MakeStrictFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConvertOctalLiteralToDecimalFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConvertOctalLiteralToDecimalFix.java
index a552caf..c4545e7 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConvertOctalLiteralToDecimalFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ConvertOctalLiteralToDecimalFix.java
@@ -25,6 +25,11 @@
class ConvertOctalLiteralToDecimalFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/DoubleLiteralMayBeFloatLiteralInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/DoubleLiteralMayBeFloatLiteralInspection.java
index ab41e96..b08e354 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/DoubleLiteralMayBeFloatLiteralInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/DoubleLiteralMayBeFloatLiteralInspection.java
@@ -107,6 +107,12 @@
replacementString);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace with 'float'";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ImplicitNumericConversionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ImplicitNumericConversionInspection.java
index 5d401d2..cee789f 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ImplicitNumericConversionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ImplicitNumericConversionInspection.java
@@ -112,6 +112,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return InspectionGadgetsBundle.message("implicit.numeric.conversion.make.explicit.quickfix");
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/IntLiteralMayBeLongLiteralInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/IntLiteralMayBeLongLiteralInspection.java
index 8b5368a..dfb4832 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/IntLiteralMayBeLongLiteralInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/IntLiteralMayBeLongLiteralInspection.java
@@ -107,6 +107,12 @@
replacementString);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace with long literal";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/LongLiteralsEndingWithLowercaseLInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/LongLiteralsEndingWithLowercaseLInspection.java
index a503387..bc78f3b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/LongLiteralsEndingWithLowercaseLInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/LongLiteralsEndingWithLowercaseLInspection.java
@@ -68,6 +68,11 @@
return InspectionGadgetsBundle.message(
"long.literals.ending.with.lowercase.l.replace.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/NonReproducibleMathCallInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/NonReproducibleMathCallInspection.java
index f6cd53c..417f3e8 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/NonReproducibleMathCallInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/NonReproducibleMathCallInspection.java
@@ -77,6 +77,11 @@
}
private static class MakeStrictFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspection.java
index beb7869..a4739cb 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspection.java
@@ -140,6 +140,11 @@
}
private class PointlessArithmeticFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/RemoveLeadingZeroFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/RemoveLeadingZeroFix.java
index b080a5d..9ddd84a1 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/RemoveLeadingZeroFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/RemoveLeadingZeroFix.java
@@ -35,6 +35,12 @@
"remove.leading.zero.to.make.decimal.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java
index 8a71995..e8bf9a9 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryExplicitNumericCastInspection.java
@@ -75,6 +75,11 @@
}
private static class UnnecessaryExplicitNumericCastFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@NotNull
@Override
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryUnaryMinusInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryUnaryMinusInspection.java
index 8ab4cf6..da8d231 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryUnaryMinusInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnnecessaryUnaryMinusInspection.java
@@ -58,6 +58,11 @@
return InspectionGadgetsBundle.message(
"unnecessary.unary.minus.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnpredictableBigDecimalConstructorCallInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnpredictableBigDecimalConstructorCallInspection.java
index d41663d..95cffc6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnpredictableBigDecimalConstructorCallInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/UnpredictableBigDecimalConstructorCallInspection.java
@@ -97,6 +97,12 @@
argumentText);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace with 'new BigDecimal'";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ArraysAsListWithZeroOrOneArgumentInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ArraysAsListWithZeroOrOneArgumentInspection.java
index c677d98..9623391 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ArraysAsListWithZeroOrOneArgumentInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ArraysAsListWithZeroOrOneArgumentInspection.java
@@ -77,6 +77,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Simplify";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement().getParent().getParent();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/BooleanConstructorInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/BooleanConstructorInspection.java
index fab1858..ce85003 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/BooleanConstructorInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/BooleanConstructorInspection.java
@@ -76,6 +76,12 @@
return InspectionGadgetsBundle.message("boolean.constructor.simplify.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiNewExpression expression = (PsiNewExpression)descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/BoxingBoxedValueInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/BoxingBoxedValueInspection.java
index e7ee81d..01e0a3e 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/BoxingBoxedValueInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/BoxingBoxedValueInspection.java
@@ -83,6 +83,12 @@
"boxing.boxed.value.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/CallToSimpleGetterInClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/CallToSimpleGetterInClassInspection.java
index a317412..f360ad1 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/CallToSimpleGetterInClassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/CallToSimpleGetterInClassInspection.java
@@ -76,6 +76,11 @@
}
private static class InlineCallFix extends InspectionGadgetsFix {
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/CallToSimpleSetterInClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/CallToSimpleSetterInClassInspection.java
index 6c5b9b6..1572b1b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/CallToSimpleSetterInClassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/CallToSimpleSetterInClassInspection.java
@@ -84,6 +84,12 @@
return InspectionGadgetsBundle.message("call.to.simple.setter.in.class.inline.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ConstantStringInternInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ConstantStringInternInspection.java
index ea205c2..ada80c6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ConstantStringInternInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ConstantStringInternInspection.java
@@ -54,6 +54,11 @@
}
private static class ConstantStringInternFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InnerClassMayBeStaticInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InnerClassMayBeStaticInspection.java
index aac5783..f4c3a3072 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InnerClassMayBeStaticInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InnerClassMayBeStaticInspection.java
@@ -54,6 +54,11 @@
}
private static class InnerClassMayBeStaticFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InstantiatingObjectToGetClassObjectInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InstantiatingObjectToGetClassObjectInspection.java
index e5a4623..9a001ed 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InstantiatingObjectToGetClassObjectInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InstantiatingObjectToGetClassObjectInspection.java
@@ -64,6 +64,12 @@
"instantiating.object.to.get.class.object.replace.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/KeySetIterationMayUseEntrySetInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/KeySetIterationMayUseEntrySetInspection.java
index 5cd9e76..053113b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/KeySetIterationMayUseEntrySetInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/KeySetIterationMayUseEntrySetInspection.java
@@ -62,6 +62,11 @@
private static class KeySetIterationMapUseEntrySetFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/LengthOneStringInIndexOfInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/LengthOneStringInIndexOfInspection.java
index 28c12bf..3207f5b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/LengthOneStringInIndexOfInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/LengthOneStringInIndexOfInspection.java
@@ -67,6 +67,11 @@
private static class ReplaceStringsWithCharsFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/LengthOneStringsInConcatenationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/LengthOneStringsInConcatenationInspection.java
index ecd9193..b776bd5 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/LengthOneStringsInConcatenationInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/LengthOneStringsInConcatenationInspection.java
@@ -70,6 +70,12 @@
"length.one.strings.in.concatenation.replace.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ManualArrayCopyInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ManualArrayCopyInspection.java
index f01ef60..cfb3199 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ManualArrayCopyInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ManualArrayCopyInspection.java
@@ -77,6 +77,11 @@
public String getName() {
return InspectionGadgetsBundle.message("manual.array.copy.replace.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ManualArrayToCollectionCopyInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ManualArrayToCollectionCopyInspection.java
index 98b77797..2c26bd5 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ManualArrayToCollectionCopyInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/ManualArrayToCollectionCopyInspection.java
@@ -70,6 +70,12 @@
"manual.array.to.collection.copy.replace.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RandomDoubleForRandomIntegerInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RandomDoubleForRandomIntegerInspection.java
index 5cc2ec9..e904f47 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RandomDoubleForRandomIntegerInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RandomDoubleForRandomIntegerInspection.java
@@ -67,6 +67,12 @@
"random.double.for.random.integer.replace.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RedundantStringFormatCallInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RedundantStringFormatCallInspection.java
index 957e987..855e584 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RedundantStringFormatCallInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RedundantStringFormatCallInspection.java
@@ -23,7 +23,6 @@
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
-import com.siyeh.ig.psiutils.FormatUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -56,6 +55,11 @@
return InspectionGadgetsBundle.message(
"redundant.string.format.call.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringBufferToStringInConcatenationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringBufferToStringInConcatenationInspection.java
index 693bb9e..40e3ccf 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringBufferToStringInConcatenationInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringBufferToStringInConcatenationInspection.java
@@ -55,6 +55,11 @@
}
private static class StringBufferToStringFix extends InspectionGadgetsFix {
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringConcatenationInsideStringBufferAppendInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringConcatenationInsideStringBufferAppendInspection.java
index b36ffaa..242c60f 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringConcatenationInsideStringBufferAppendInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringConcatenationInsideStringBufferAppendInspection.java
@@ -62,6 +62,11 @@
}
private static class ReplaceWithChainedAppendFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringConstructorInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringConstructorInspection.java
index 9ab5e74..1390475 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringConstructorInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringConstructorInspection.java
@@ -103,6 +103,12 @@
return m_name;
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Simplify";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringEqualsEmptyStringInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringEqualsEmptyStringInspection.java
index ab59be4..8a87343 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringEqualsEmptyStringInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringEqualsEmptyStringInspection.java
@@ -75,6 +75,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Simplify empty string check";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiIdentifier name = (PsiIdentifier)descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringToStringInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringToStringInspection.java
index d955fd2..2376f75 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringToStringInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/StringToStringInspection.java
@@ -71,6 +71,12 @@
"constant.conditional.expression.simplify.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/SubstringZeroInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/SubstringZeroInspection.java
index 2707170..7ed0a20 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/SubstringZeroInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/SubstringZeroInspection.java
@@ -62,6 +62,12 @@
"constant.conditional.expression.simplify.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/TailRecursionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/TailRecursionInspection.java
index 58f0b89..b9c8c4b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/TailRecursionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/TailRecursionInspection.java
@@ -78,6 +78,12 @@
"tail.recursion.replace.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/TrivialStringConcatenationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/TrivialStringConcatenationInspection.java
index 4b72244..43516f1 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/TrivialStringConcatenationInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/TrivialStringConcatenationInspection.java
@@ -148,6 +148,12 @@
return m_name;
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace concatenation";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiLiteralExpression expression = (PsiLiteralExpression)descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/UnnecessaryTemporaryOnConversionFromStringInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/UnnecessaryTemporaryOnConversionFromStringInspection.java
index f37ccc7..6295e1b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/UnnecessaryTemporaryOnConversionFromStringInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/UnnecessaryTemporaryOnConversionFromStringInspection.java
@@ -147,6 +147,13 @@
return m_name;
}
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Simplify";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/UnnecessaryTemporaryOnConversionToStringInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/UnnecessaryTemporaryOnConversionToStringInspection.java
index 7e8a4af..d4e814a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/UnnecessaryTemporaryOnConversionToStringInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/UnnecessaryTemporaryOnConversionToStringInspection.java
@@ -112,6 +112,12 @@
return m_name;
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Simplify";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/redundancy/UnusedLabelInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/redundancy/UnusedLabelInspection.java
index 7a1530d6..8326614 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/redundancy/UnusedLabelInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/redundancy/UnusedLabelInspection.java
@@ -56,6 +56,11 @@
}
private static class UnusedLabelFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/ChannelResourceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/ChannelResourceInspection.java
index e02e89d..c9dc2d8 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/ChannelResourceInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/ChannelResourceInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,22 +15,15 @@
*/
package com.siyeh.ig.resources;
-import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.HardcodedMethodConstants;
import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
-
public class ChannelResourceInspection extends ResourceInspection {
- @SuppressWarnings({"PublicField"})
- public boolean insideTryAllowed = false;
-
@Override
@NotNull
public String getID() {
@@ -40,115 +33,58 @@
@Override
@NotNull
public String getDisplayName() {
- return InspectionGadgetsBundle.message(
- "channel.opened.not.closed.display.name");
+ return InspectionGadgetsBundle.message("channel.opened.not.closed.display.name");
}
- @Override
- @NotNull
- public String buildErrorString(Object... infos) {
- final PsiExpression expression = (PsiExpression)infos[0];
- final PsiType type = expression.getType();
- assert type != null;
- final String text = type.getPresentableText();
- return InspectionGadgetsBundle.message(
- "channel.opened.not.closed.problem.descriptor", text);
- }
-
- @Override
- public JComponent createOptionsPanel() {
- return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message(
- "allow.resource.to.be.opened.inside.a.try.block"),
- this, "insideTryAllowed");
- }
-
- @Override
- public BaseInspectionVisitor buildVisitor() {
- return new ChannelResourceVisitor();
- }
-
- private class ChannelResourceVisitor extends BaseInspectionVisitor {
-
- @Override
- public void visitMethodCallExpression(
- @NotNull PsiMethodCallExpression expression) {
- super.visitMethodCallExpression(expression);
- if (!isChannelFactoryMethod(expression)) {
- return;
- }
- final PsiElement parent = getExpressionParent(expression);
- if (parent instanceof PsiReturnStatement ||
- parent instanceof PsiResourceVariable) {
- return;
- }
- final PsiVariable boundVariable = getVariable(parent);
- if (isSafelyClosed(boundVariable, expression, insideTryAllowed)) {
- return;
- }
- if (isChannelFactoryClosedInFinally(expression)) {
- return;
- }
- if (isResourceEscapedFromMethod(boundVariable, expression)) {
- return;
- }
- registerError(expression, expression);
+ protected boolean isResourceCreation(PsiExpression expression) {
+ if (!(expression instanceof PsiMethodCallExpression)) {
+ return false;
}
+ final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
+ final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
+ final String methodName = methodExpression.getReferenceName();
+ if (!HardcodedMethodConstants.GET_CHANNEL.equals(methodName)) {
+ return false;
+ }
+ final PsiExpression qualifier = methodExpression.getQualifierExpression();
+ if (qualifier == null ||
+ TypeUtils.expressionHasTypeOrSubtype(qualifier,
+ "java.net.Socket", "java.net.DatagramSocket", "java.net.ServerSocket",
+ "java.net.SocketInputStream", "java.net.SocketOutputStream", "java.io.FileInputStream",
+ "java.io.FileOutputStream", "java.io.RandomAccessFile",
+ "com.sun.corba.se.pept.transport.EventHandler", "sun.nio.ch.InheritedChannel") == null) {
+ return false;
+ }
+ return TypeUtils.expressionHasTypeOrSubtype(expression, "java.nio.channels.Channel");
+ }
- private boolean isChannelFactoryClosedInFinally(
- PsiMethodCallExpression expression) {
- final PsiReferenceExpression methodExpression =
- expression.getMethodExpression();
- final PsiExpression qualifier =
- methodExpression.getQualifierExpression();
- if (!(qualifier instanceof PsiReferenceExpression)) {
- return false;
- }
- final PsiReferenceExpression referenceExpression =
- (PsiReferenceExpression)qualifier;
- final PsiElement target = referenceExpression.resolve();
- if (!(target instanceof PsiVariable)) {
- return false;
- }
- final PsiVariable variable = (PsiVariable)target;
- PsiTryStatement tryStatement =
- PsiTreeUtil.getParentOfType(expression,
- PsiTryStatement.class, true, PsiMember.class);
+ @Override
+ protected boolean isResourceFactoryClosed(PsiExpression expression, boolean insideTryAllowed) {
+ if (!(expression instanceof PsiMethodCallExpression)) {
+ return false;
+ }
+ final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
+ final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
+ final PsiExpression qualifier = methodExpression.getQualifierExpression();
+ if (!(qualifier instanceof PsiReferenceExpression)) {
+ return false;
+ }
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)qualifier;
+ final PsiElement target = referenceExpression.resolve();
+ if (!(target instanceof PsiVariable)) {
+ return false;
+ }
+ final PsiVariable variable = (PsiVariable)target;
+ PsiTryStatement tryStatement = PsiTreeUtil.getParentOfType(expression, PsiTryStatement.class, true, PsiMember.class);
+ if (tryStatement == null) {
+ return false;
+ }
+ while (!isResourceClosedInFinally(tryStatement, variable)) {
+ tryStatement = PsiTreeUtil.getParentOfType(tryStatement, PsiTryStatement.class, true, PsiMember.class);
if (tryStatement == null) {
return false;
}
- while (!isResourceClosedInFinally(tryStatement, variable)) {
- tryStatement =
- PsiTreeUtil.getParentOfType(tryStatement,
- PsiTryStatement.class, true, PsiMember.class);
- if (tryStatement == null) {
- return false;
- }
- }
- return true;
}
-
- private boolean isChannelFactoryMethod(
- PsiMethodCallExpression expression) {
- final PsiReferenceExpression methodExpression =
- expression.getMethodExpression();
- final String methodName = methodExpression.getReferenceName();
- if (!HardcodedMethodConstants.GET_CHANNEL.equals(methodName)) {
- return false;
- }
- final PsiExpression qualifier =
- methodExpression.getQualifierExpression();
- if (qualifier == null) {
- return false;
- }
- return TypeUtils.expressionHasTypeOrSubtype(qualifier,
- "java.net.Socket",
- "java.net.DatagramSocket",
- "java.net.ServerSocket",
- "java.io.FileInputStream",
- "java.io.FileOutputStream",
- "java.io.RandomAccessFile",
- "com.sun.corba.se.pept.transport.EventHandler",
- "sun.nio.ch.InheritedChannel") != null;
- }
+ return true;
}
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/HibernateResourceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/HibernateResourceInspection.java
index 945e0e5..80a590d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/HibernateResourceInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/HibernateResourceInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,21 +15,16 @@
*/
package com.siyeh.ig.resources;
-import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
-import com.intellij.psi.*;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiMethodCallExpression;
+import com.intellij.psi.PsiReferenceExpression;
import com.siyeh.HardcodedMethodConstants;
import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
-
public class HibernateResourceInspection extends ResourceInspection {
- @SuppressWarnings({"PublicField"})
- public boolean insideTryAllowed = false;
-
@Override
@NotNull
public String getID() {
@@ -39,72 +34,20 @@
@Override
@NotNull
public String getDisplayName() {
- return InspectionGadgetsBundle.message(
- "hibernate.resource.opened.not.closed.display.name");
+ return InspectionGadgetsBundle.message("hibernate.resource.opened.not.closed.display.name");
}
- @Override
- @NotNull
- public String buildErrorString(Object... infos) {
- final PsiExpression expression = (PsiExpression)infos[0];
- final PsiType type = expression.getType();
- assert type != null;
- final String text = type.getPresentableText();
- return InspectionGadgetsBundle.message(
- "hibernate.resource.opened.not.closed.problem.descriptor",
- text);
- }
-
- @Override
- public JComponent createOptionsPanel() {
- return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message(
- "allow.resource.to.be.opened.inside.a.try.block"),
- this, "insideTryAllowed");
- }
-
- @Override
- public BaseInspectionVisitor buildVisitor() {
- return new HibernateResourceVisitor();
- }
-
- private class HibernateResourceVisitor extends BaseInspectionVisitor {
-
- @Override
- public void visitMethodCallExpression(
- @NotNull PsiMethodCallExpression expression) {
- super.visitMethodCallExpression(expression);
- if (!isHibernateFactoryMethod(expression)) {
- return;
- }
- final PsiElement parent = getExpressionParent(expression);
- if (parent instanceof PsiReturnStatement) {
- return;
- }
- final PsiVariable boundVariable = getVariable(parent);
- if (isSafelyClosed(boundVariable, expression, insideTryAllowed)) {
- return;
- }
- if (isResourceEscapedFromMethod(boundVariable, expression)) {
- return;
- }
- registerError(expression, expression);
+ protected boolean isResourceCreation(PsiExpression expression) {
+ if (!(expression instanceof PsiMethodCallExpression)) {
+ return false;
}
-
- private boolean isHibernateFactoryMethod(
- PsiMethodCallExpression expression) {
- final PsiReferenceExpression methodExpression =
- expression.getMethodExpression();
- final String methodName = methodExpression.getReferenceName();
- if (!HardcodedMethodConstants.OPEN_SESSION.equals(methodName)) {
- return false;
- }
- final PsiExpression qualifier =
- methodExpression.getQualifierExpression();
- if (qualifier == null) {
- return false;
- }
- return TypeUtils.expressionHasTypeOrSubtype(qualifier,
- "org.hibernate.SessionFactory");
+ final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
+ final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
+ final String methodName = methodExpression.getReferenceName();
+ if (!HardcodedMethodConstants.OPEN_SESSION.equals(methodName)) {
+ return false;
}
+ final PsiExpression qualifier = methodExpression.getQualifierExpression();
+ return qualifier != null && TypeUtils.expressionHasTypeOrSubtype(qualifier, "org.hibernate.SessionFactory");
}
}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/IOResourceInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/IOResourceInspectionBase.java
index 36078e1..31ac244 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/IOResourceInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/IOResourceInspectionBase.java
@@ -18,9 +18,7 @@
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -30,10 +28,11 @@
import java.util.List;
public class IOResourceInspectionBase extends ResourceInspection {
- protected static final String[] IO_TYPES = {
- "java.io.InputStream", "java.io.OutputStream",
- "java.io.Reader", "java.io.Writer",
- "java.io.RandomAccessFile", "java.util.zip.ZipFile"};
+ protected static final String[] IO_TYPES =
+ {
+ "java.io.InputStream", "java.io.OutputStream", "java.io.Reader", "java.io.Writer",
+ "java.io.RandomAccessFile", "java.util.zip.ZipFile"
+ };
final List<String> ignoredTypes = new ArrayList();
public IOResourceInspectionBase() {
@@ -50,18 +49,6 @@
',' + "java.io.StringWriter" +
',' + "java.io.StringReader";
@SuppressWarnings({"PublicField"})
- public boolean insideTryAllowed = false;
-
- public static boolean isIOResourceFactoryMethodCall(PsiMethodCallExpression expression) {
- final PsiReferenceExpression methodExpression = expression.getMethodExpression();
- @NonNls final String methodName = methodExpression.getReferenceName();
- if (!"getResourceAsStream".equals(methodName)) {
- return false;
- }
- final PsiExpression qualifier = methodExpression.getQualifierExpression();
- return qualifier != null &&
- TypeUtils.expressionHasTypeOrSubtype(qualifier, CommonClassNames.JAVA_LANG_CLASS, "java.lang.ClassLoader") != null;
- }
@Override
@NotNull
@@ -72,19 +59,7 @@
@Override
@NotNull
public String getDisplayName() {
- return InspectionGadgetsBundle.message(
- "i.o.resource.opened.not.closed.display.name");
- }
-
- @Override
- @NotNull
- public String buildErrorString(Object... infos) {
- final PsiExpression expression = (PsiExpression)infos[0];
- final PsiType type = expression.getType();
- assert type != null;
- final String text = type.getPresentableText();
- return InspectionGadgetsBundle.message(
- "resource.opened.not.closed.problem.descriptor", text);
+ return InspectionGadgetsBundle.message("i.o.resource.opened.not.closed.display.name");
}
@Override
@@ -100,122 +75,28 @@
}
@Override
- public BaseInspectionVisitor buildVisitor() {
- return new IOResourceVisitor();
- }
-
- public boolean isIOResource(PsiExpression expression) {
- return TypeUtils.expressionHasTypeOrSubtype(expression, IO_TYPES) != null && !isIgnoredType(expression);
+ public boolean isResourceCreation(PsiExpression expression) {
+ if (expression instanceof PsiNewExpression) {
+ return TypeUtils.expressionHasTypeOrSubtype(expression, IO_TYPES) != null && !isIgnoredType(expression);
+ }
+ else if (expression instanceof PsiMethodCallExpression) {
+ final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
+ final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
+ @NonNls final String methodName = methodExpression.getReferenceName();
+ if (!"getResourceAsStream".equals(methodName)) {
+ return false;
+ }
+ final PsiExpression qualifier = methodExpression.getQualifierExpression();
+ if (qualifier == null ||
+ TypeUtils.expressionHasTypeOrSubtype(qualifier, CommonClassNames.JAVA_LANG_CLASS, "java.lang.ClassLoader") == null) {
+ return false;
+ }
+ return TypeUtils.expressionHasTypeOrSubtype(expression, "java.io.InputStream");
+ }
+ return false;
}
private boolean isIgnoredType(PsiExpression expression) {
return TypeUtils.expressionHasTypeOrSubtype(expression, ignoredTypes);
}
-
- private boolean isArgumentOfResourceCreation(
- PsiVariable boundVariable, PsiElement scope) {
- final UsedAsIOResourceArgumentVisitor visitor =
- new UsedAsIOResourceArgumentVisitor(boundVariable);
- scope.accept(visitor);
- return visitor.isUsedAsArgumentToResourceCreation();
- }
-
- private class IOResourceVisitor extends BaseInspectionVisitor {
-
- IOResourceVisitor() {
- }
-
- @Override
- public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
- if (!isIOResourceFactoryMethodCall(expression)) {
- return;
- }
- checkExpression(expression);
- }
-
- @Override
- public void visitNewExpression(@NotNull PsiNewExpression expression) {
- super.visitNewExpression(expression);
- if (!isIOResource(expression)) {
- return;
- }
- checkExpression(expression);
- }
-
- private void checkExpression(PsiExpression expression) {
- final PsiElement parent = getExpressionParent(expression);
- if (parent instanceof PsiReturnStatement || parent instanceof PsiResourceVariable) {
- return;
- }
- if (parent instanceof PsiExpressionList) {
- PsiElement grandParent = parent.getParent();
- if (grandParent instanceof PsiAnonymousClass) {
- grandParent = grandParent.getParent();
- }
- if (grandParent instanceof PsiNewExpression && isIOResource((PsiNewExpression)grandParent)) {
- return;
- }
- }
- final PsiVariable boundVariable = getVariable(parent);
- final PsiElement containingBlock = PsiTreeUtil.getParentOfType(expression, PsiCodeBlock.class);
- if (containingBlock == null) {
- return;
- }
- if (isArgumentOfResourceCreation(boundVariable, containingBlock)) {
- return;
- }
- if (isSafelyClosed(boundVariable, expression, insideTryAllowed)) {
- return;
- }
- if (isResourceEscapedFromMethod(boundVariable, expression)) {
- return;
- }
- registerError(expression, expression);
- }
- }
-
- private class UsedAsIOResourceArgumentVisitor
- extends JavaRecursiveElementVisitor {
-
- private boolean usedAsArgToResourceCreation = false;
- private final PsiVariable ioResource;
-
- UsedAsIOResourceArgumentVisitor(PsiVariable ioResource) {
- this.ioResource = ioResource;
- }
-
- @Override
- public void visitNewExpression(
- @NotNull PsiNewExpression expression) {
- if (usedAsArgToResourceCreation) {
- return;
- }
- super.visitNewExpression(expression);
- if (!isIOResource(expression)) {
- return;
- }
- final PsiExpressionList argumentList = expression.getArgumentList();
- if (argumentList == null) {
- return;
- }
- final PsiExpression[] arguments = argumentList.getExpressions();
- if (arguments.length == 0) {
- return;
- }
- final PsiExpression argument = arguments[0];
- if (!(argument instanceof PsiReferenceExpression)) {
- return;
- }
- final PsiReference reference = (PsiReference)argument;
- final PsiElement target = reference.resolve();
- if (target == null || !target.equals(ioResource)) {
- return;
- }
- usedAsArgToResourceCreation = true;
- }
-
- public boolean isUsedAsArgumentToResourceCreation() {
- return usedAsArgToResourceCreation;
- }
- }
-}
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/JDBCResourceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/JDBCResourceInspection.java
index a14ee5c..cdbc528 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/JDBCResourceInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/JDBCResourceInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,15 +15,12 @@
*/
package com.siyeh.ig.resources;
-import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.psi.*;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspectionVisitor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
import java.util.HashSet;
import java.util.Set;
@@ -56,11 +53,7 @@
};
@SuppressWarnings({"StaticCollection"})
- private static final Set<String> creationMethodNameSet =
- new HashSet<String>(9);
-
- @SuppressWarnings({"PublicField"})
- public boolean insideTryAllowed = false;
+ private static final Set<String> creationMethodNameSet = new HashSet<String>(9);
static {
ContainerUtil.addAll(creationMethodNameSet, creationMethodName);
@@ -75,89 +68,39 @@
@Override
@NotNull
public String getDisplayName() {
- return InspectionGadgetsBundle.message(
- "jdbc.resource.opened.not.closed.display.name");
+ return InspectionGadgetsBundle.message("jdbc.resource.opened.not.closed.display.name");
}
- @Override
- @NotNull
- public String buildErrorString(Object... infos) {
- final PsiExpression expression = (PsiExpression)infos[0];
- final PsiType type = expression.getType();
- assert type != null;
- final String text = type.getPresentableText();
- return InspectionGadgetsBundle.message(
- "jdbc.resource.opened.not.closed.problem.descriptor", text);
- }
-
- @Override
- public JComponent createOptionsPanel() {
- return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message(
- "allow.resource.to.be.opened.inside.a.try.block"),
- this, "insideTryAllowed");
- }
-
- @Override
- public BaseInspectionVisitor buildVisitor() {
- return new JDBCResourceVisitor();
- }
-
- private class JDBCResourceVisitor extends BaseInspectionVisitor {
-
- @Override
- public void visitMethodCallExpression(
- @NotNull PsiMethodCallExpression expression) {
- super.visitMethodCallExpression(expression);
- if (!isJDBCResourceCreation(expression)) {
- return;
- }
- final PsiElement parent = getExpressionParent(expression);
- if (parent instanceof PsiReturnStatement ||
- parent instanceof PsiResourceVariable) {
- return;
- }
- final PsiVariable boundVariable = getVariable(parent);
- if (isSafelyClosed(boundVariable, expression, insideTryAllowed)) {
- return;
- }
- if (isResourceEscapedFromMethod(boundVariable, expression)) {
- return;
- }
- registerError(expression, expression);
- }
-
- private boolean isJDBCResourceCreation(
- PsiMethodCallExpression expression) {
- final PsiReferenceExpression methodExpression =
- expression.getMethodExpression();
- final String name = methodExpression.getReferenceName();
- if (name == null) {
- return false;
- }
- if (!creationMethodNameSet.contains(name)) {
- return false;
- }
- final PsiMethod method = expression.resolveMethod();
- if (method == null) {
- return false;
- }
- for (int i = 0; i < creationMethodName.length; i++) {
- if (!name.equals(creationMethodName[i])) {
- continue;
- }
- final PsiClass containingClass = method.getContainingClass();
- if (containingClass == null) {
- return false;
- }
- final String className = containingClass.getQualifiedName();
- if (className == null) {
- return false;
- }
- if (className.equals(creationMethodClassName[i])) {
- return true;
- }
- }
+ protected boolean isResourceCreation(PsiExpression expression) {
+ if (!(expression instanceof PsiMethodCallExpression)) {
return false;
}
+ final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
+ final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
+ final String name = methodExpression.getReferenceName();
+ if (name == null || !creationMethodNameSet.contains(name)) {
+ return false;
+ }
+ final PsiMethod method = methodCallExpression.resolveMethod();
+ if (method == null) {
+ return false;
+ }
+ for (int i = 0; i < creationMethodName.length; i++) {
+ if (!name.equals(creationMethodName[i])) {
+ continue;
+ }
+ final PsiClass containingClass = method.getContainingClass();
+ if (containingClass == null) {
+ return false;
+ }
+ final String className = containingClass.getQualifiedName();
+ if (className == null) {
+ return false;
+ }
+ if (className.equals(creationMethodClassName[i])) {
+ return true;
+ }
+ }
+ return false;
}
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/JNDIResourceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/JNDIResourceInspection.java
index dd4097c..54148b3 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/JNDIResourceInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/JNDIResourceInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,21 +15,17 @@
*/
package com.siyeh.ig.resources;
-import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
-import com.intellij.psi.*;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiMethodCallExpression;
+import com.intellij.psi.PsiNewExpression;
+import com.intellij.psi.PsiReferenceExpression;
import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
-
public class JNDIResourceInspection extends ResourceInspection {
- @SuppressWarnings({"PublicField"})
- public boolean insideTryAllowed = false;
-
@Override
@NotNull
public String getID() {
@@ -39,118 +35,36 @@
@Override
@NotNull
public String getDisplayName() {
- return InspectionGadgetsBundle.message(
- "jndi.resource.opened.not.closed.display.name");
+ return InspectionGadgetsBundle.message("jndi.resource.opened.not.closed.display.name");
}
- @Override
- @NotNull
- public String buildErrorString(Object... infos) {
- final PsiExpression expression = (PsiExpression)infos[0];
- final PsiType type = expression.getType();
- assert type != null;
- final String text = type.getPresentableText();
- return InspectionGadgetsBundle.message(
- "resource.opened.not.closed.problem.descriptor", text);
- }
-
- @Override
- public JComponent createOptionsPanel() {
- return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message(
- "allow.resource.to.be.opened.inside.a.try.block"),
- this, "insideTryAllowed");
- }
-
- @Override
- public BaseInspectionVisitor buildVisitor() {
- return new JNDIResourceVisitor();
- }
-
- private class JNDIResourceVisitor extends BaseInspectionVisitor {
-
- @NonNls
- private static final String LIST = "list";
- @NonNls
- private static final String LIST_BINDING = "listBindings";
- @NonNls
- private static final String GET_ALL = "getAll";
-
- @Override
- public void visitMethodCallExpression(
- @NotNull PsiMethodCallExpression expression) {
- super.visitMethodCallExpression(expression);
- if (!isJNDIFactoryMethod(expression)) {
- return;
- }
- final PsiElement parent = getExpressionParent(expression);
- if (parent instanceof PsiReturnStatement) {
- return;
- }
- final PsiVariable boundVariable = getVariable(parent);
- if (isSafelyClosed(boundVariable, expression, insideTryAllowed)) {
- return;
- }
- if (isResourceEscapedFromMethod(boundVariable, expression)) {
- return;
- }
- registerError(expression, expression);
- }
-
-
- @Override
- public void visitNewExpression(
- @NotNull PsiNewExpression expression) {
- super.visitNewExpression(expression);
- if (!isJNDIResource(expression)) {
- return;
- }
- final PsiElement parent = getExpressionParent(expression);
- if (parent instanceof PsiReturnStatement) {
- return;
- }
- final PsiVariable boundVariable = getVariable(parent);
- if (isSafelyClosed(boundVariable, expression, insideTryAllowed)) {
- return;
- }
- if (isResourceEscapedFromMethod(boundVariable, expression)) {
- return;
- }
- registerError(expression, expression);
- }
-
- private boolean isJNDIResource(PsiNewExpression expression) {
- return TypeUtils.expressionHasTypeOrSubtype(expression,
- "javax.naming.InitialContext");
- }
-
- private boolean isJNDIFactoryMethod(
- PsiMethodCallExpression expression) {
- final PsiReferenceExpression methodExpression =
- expression.getMethodExpression();
- final String methodName = methodExpression.getReferenceName();
- if (LIST.equals(methodName) || LIST_BINDING.equals(methodName)) {
- final PsiExpression qualifier =
- methodExpression.getQualifierExpression();
+ protected boolean isResourceCreation(PsiExpression expression) {
+ if (expression instanceof PsiMethodCallExpression) {
+ final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
+ final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
+ @NonNls final String methodName = methodExpression.getReferenceName();
+ if ("list".equals(methodName) || "listBindings".equals(methodName)) {
+ final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (qualifier == null) {
return false;
}
- return TypeUtils.expressionHasTypeOrSubtype(qualifier,
- "javax.naming.Context");
+ return TypeUtils.expressionHasTypeOrSubtype(qualifier, "javax.naming.Context");
}
- else if (GET_ALL.equals(methodName)) {
- final PsiExpression qualifier =
- methodExpression.getQualifierExpression();
+ else if ("getAll".equals(methodName)) {
+ final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (qualifier == null) {
return false;
}
- return TypeUtils.expressionHasTypeOrSubtype(qualifier,
- "javax.naming.directory.Attribute") ||
- TypeUtils.expressionHasTypeOrSubtype(qualifier,
- "javax.naming.directory.Attributes");
+ return TypeUtils.expressionHasTypeOrSubtype(qualifier, "javax.naming.directory.Attribute", "javax.naming.directory.Attributes") !=
+ null;
}
else {
return false;
}
}
+ else if (expression instanceof PsiNewExpression) {
+ return TypeUtils.expressionHasTypeOrSubtype(expression, "javax.naming.InitialContext");
+ }
+ return false;
}
}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/ResourceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/ResourceInspection.java
index 86f74e5..67f5c33 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/ResourceInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/ResourceInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2011 Bas Leijdekkers
+ * Copyright 2008-2013 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,53 +15,109 @@
*/
package com.siyeh.ig.resources;
+import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.siyeh.HardcodedMethodConstants;
+import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.psiutils.ParenthesesUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
+
public abstract class ResourceInspection extends BaseInspection {
+ @SuppressWarnings({"PublicField"})
+ public boolean insideTryAllowed = false;
+
+ @Override
+ public JComponent createOptionsPanel() {
+ return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("allow.resource.to.be.opened.inside.a.try.block"),
+ this, "insideTryAllowed");
+ }
+
+ @Override
+ @NotNull
+ public String buildErrorString(Object... infos) {
+ final PsiExpression expression = (PsiExpression)infos[0];
+ final PsiType type = expression.getType();
+ assert type != null;
+ final String text = type.getPresentableText();
+ return InspectionGadgetsBundle.message("resource.opened.not.closed.problem.descriptor", text);
+ }
+
+ @Override
+ public final BaseInspectionVisitor buildVisitor() {
+ return new ResourceVisitor();
+ }
+
+ private class ResourceVisitor extends BaseInspectionVisitor {
+ @Override
+ public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
+ super.visitMethodCallExpression(expression);
+ checkExpression(expression);
+ }
+
+ @Override
+ public void visitNewExpression(@NotNull PsiNewExpression expression) {
+ super.visitNewExpression(expression);
+ checkExpression(expression);
+ }
+
+ private void checkExpression(PsiExpression expression) {
+ if (!isResourceCreation(expression)) {
+ return;
+ }
+ final PsiVariable boundVariable = getVariable(expression);
+ if (isSafelyClosed(boundVariable, expression, insideTryAllowed)) {
+ return;
+ }
+ if (isResourceFactoryClosed(expression, insideTryAllowed)) {
+ return;
+ }
+ if (isResourceEscapingFromMethod(boundVariable, expression)) {
+ return;
+ }
+ registerError(expression, expression);
+ }
+ }
+
+ protected abstract boolean isResourceCreation(PsiExpression expression);
+
+ protected boolean isResourceFactoryClosed(PsiExpression expression, boolean insideTryAllowed) {
+ return false;
+ }
+
@Nullable
- protected static PsiVariable getVariable(
- @NotNull PsiElement element) {
- if (element instanceof PsiAssignmentExpression) {
- final PsiAssignmentExpression assignment =
- (PsiAssignmentExpression)element;
+ private static PsiVariable getVariable(@NotNull PsiExpression expression) {
+ final PsiElement parent = ParenthesesUtils.getParentSkipParentheses(expression);
+ if (parent instanceof PsiAssignmentExpression) {
+ final PsiAssignmentExpression assignment = (PsiAssignmentExpression)parent;
final PsiExpression lhs = assignment.getLExpression();
if (!(lhs instanceof PsiReferenceExpression)) {
return null;
}
- final PsiReferenceExpression referenceExpression =
- (PsiReferenceExpression)lhs;
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)lhs;
final PsiElement referent = referenceExpression.resolve();
if (!(referent instanceof PsiVariable)) {
return null;
}
return (PsiVariable)referent;
}
- else if (element instanceof PsiVariable) {
- return (PsiVariable)element;
+ else if (parent instanceof PsiVariable) {
+ return (PsiVariable)parent;
}
else {
return null;
}
}
- protected static PsiElement getExpressionParent(PsiExpression expression) {
- PsiElement parent = expression.getParent();
- while (parent instanceof PsiParenthesizedExpression ||
- parent instanceof PsiTypeCastExpression) {
- parent = parent.getParent();
- }
- return parent;
- }
-
- protected static boolean isSafelyClosed(@Nullable PsiVariable variable, PsiElement context, boolean insideTryAllowed) {
+ private static boolean isSafelyClosed(@Nullable PsiVariable variable, PsiElement context, boolean insideTryAllowed) {
if (variable == null) {
return false;
}
@@ -104,9 +160,7 @@
return isResourceClose(nextStatement, variable);
}
- protected static boolean isResourceClosedInFinally(
- @NotNull PsiTryStatement tryStatement,
- @NotNull PsiVariable variable) {
+ protected static boolean isResourceClosedInFinally(@NotNull PsiTryStatement tryStatement, @NotNull PsiVariable variable) {
final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock();
if (finallyBlock == null) {
return false;
@@ -120,18 +174,14 @@
return visitor.containsClose();
}
- private static boolean isResourceClose(PsiStatement statement,
- PsiVariable variable) {
+ private static boolean isResourceClose(PsiStatement statement, PsiVariable variable) {
if (statement instanceof PsiExpressionStatement) {
- final PsiExpressionStatement expressionStatement =
- (PsiExpressionStatement)statement;
- final PsiExpression expression =
- expressionStatement.getExpression();
+ final PsiExpressionStatement expressionStatement = (PsiExpressionStatement)statement;
+ final PsiExpression expression = expressionStatement.getExpression();
if (!(expression instanceof PsiMethodCallExpression)) {
return false;
}
- final PsiMethodCallExpression methodCallExpression =
- (PsiMethodCallExpression)expression;
+ final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
return isResourceClose(methodCallExpression, variable);
}
else if (statement instanceof PsiTryStatement) {
@@ -154,10 +204,8 @@
if (!(condition instanceof PsiBinaryExpression)) {
return false;
}
- final PsiBinaryExpression binaryExpression =
- (PsiBinaryExpression)condition;
- final IElementType tokenType =
- binaryExpression.getOperationTokenType();
+ final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)condition;
+ final IElementType tokenType = binaryExpression.getOperationTokenType();
if (JavaTokenType.NE != tokenType) {
return false;
}
@@ -170,8 +218,7 @@
if (!(rhs instanceof PsiReferenceExpression)) {
return false;
}
- final PsiReferenceExpression referenceExpression =
- (PsiReferenceExpression)rhs;
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)rhs;
final PsiElement target = referenceExpression.resolve();
if (!variable.equals(target)) {
return false;
@@ -181,8 +228,7 @@
if (!(lhs instanceof PsiReferenceExpression)) {
return false;
}
- final PsiReferenceExpression referenceExpression =
- (PsiReferenceExpression)lhs;
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)lhs;
final PsiElement target = referenceExpression.resolve();
if (!variable.equals(target)) {
return false;
@@ -192,44 +238,21 @@
return isResourceClose(thenBranch, variable);
}
else if (statement instanceof PsiBlockStatement) {
- final PsiBlockStatement blockStatement =
- (PsiBlockStatement)statement;
+ final PsiBlockStatement blockStatement = (PsiBlockStatement)statement;
final PsiCodeBlock codeBlock = blockStatement.getCodeBlock();
final PsiStatement[] statements = codeBlock.getStatements();
- return statements.length != 0 &&
- isResourceClose(statements[0], variable);
+ return statements.length != 0 && isResourceClose(statements[0], variable);
}
return false;
}
- protected static boolean isResourceEscapedFromMethod(
- PsiVariable boundVariable, PsiElement context) {
- // poor man dataflow
- final PsiMethod method =
- PsiTreeUtil.getParentOfType(context, PsiMethod.class, true,
- PsiMember.class);
- if (method == null) {
- return false;
- }
- final PsiCodeBlock body = method.getBody();
- if (body == null) {
- return false;
- }
- final EscapeVisitor visitor = new EscapeVisitor(boundVariable);
- body.accept(visitor);
- return visitor.isEscaped();
- }
-
- protected static boolean isResourceClose(PsiMethodCallExpression call,
- PsiVariable resource) {
- final PsiReferenceExpression methodExpression =
- call.getMethodExpression();
+ private static boolean isResourceClose(PsiMethodCallExpression call, PsiVariable resource) {
+ final PsiReferenceExpression methodExpression = call.getMethodExpression();
final String methodName = methodExpression.getReferenceName();
if (!HardcodedMethodConstants.CLOSE.equals(methodName)) {
return false;
}
- final PsiExpression qualifier =
- methodExpression.getQualifierExpression();
+ final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (!(qualifier instanceof PsiReferenceExpression)) {
return false;
}
@@ -238,6 +261,46 @@
return referent != null && referent.equals(resource);
}
+ private static boolean isResourceEscapingFromMethod(PsiVariable boundVariable, PsiExpression resourceCreationExpression) {
+ final PsiElement parent = ParenthesesUtils.getParentSkipParentheses(resourceCreationExpression);
+ if (parent instanceof PsiReturnStatement || parent instanceof PsiResourceVariable) {
+ return true;
+ }
+ else if (parent instanceof PsiAssignmentExpression) {
+ final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)parent;
+ if (ParenthesesUtils.stripParentheses(assignmentExpression.getRExpression()) != resourceCreationExpression) {
+ return true; // non-sensical code
+ }
+ final PsiExpression lhs = ParenthesesUtils.stripParentheses(assignmentExpression.getLExpression());
+ if (lhs instanceof PsiReferenceExpression) {
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)lhs;
+ final PsiElement target = referenceExpression.resolve();
+ if (target instanceof PsiField) {
+ return true;
+ }
+ }
+ }
+ else if (parent instanceof PsiExpressionList) {
+ PsiElement grandParent = parent.getParent();
+ if (grandParent instanceof PsiAnonymousClass) {
+ grandParent = grandParent.getParent();
+ }
+ if (grandParent instanceof PsiCallExpression) {
+ return true;
+ }
+ }
+ if (boundVariable == null) {
+ return false;
+ }
+ final PsiCodeBlock codeBlock = PsiTreeUtil.getParentOfType(resourceCreationExpression, PsiCodeBlock.class, true, PsiMember.class);
+ if (codeBlock == null) {
+ return false;
+ }
+ final EscapeVisitor visitor = new EscapeVisitor(boundVariable);
+ codeBlock.accept(visitor);
+ return visitor.isEscaped();
+ }
+
private static class CloseVisitor extends JavaRecursiveElementVisitor {
private boolean containsClose = false;
@@ -270,8 +333,7 @@
}
@Override
- public void visitReferenceExpression(
- PsiReferenceExpression referenceExpression) {
+ public void visitReferenceExpression(PsiReferenceExpression referenceExpression) {
// check if resource is closed in a method like IOUtils.silentClose()
super.visitReferenceExpression(referenceExpression);
if (containsClose) {
@@ -294,8 +356,7 @@
if (!(grandParent instanceof PsiMethodCallExpression)) {
return;
}
- final PsiMethodCallExpression methodCallExpression =
- (PsiMethodCallExpression)grandParent;
+ final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)grandParent;
final PsiElement target = referenceExpression.resolve();
if (target == null || !target.equals(resource)) {
return;
@@ -333,13 +394,12 @@
private final PsiVariable boundVariable;
private boolean escaped = false;
- public EscapeVisitor(PsiVariable boundVariable) {
+ public EscapeVisitor(@NotNull PsiVariable boundVariable) {
this.boundVariable = boundVariable;
}
@Override
- public void visitAnonymousClass(PsiAnonymousClass aClass) {
- }
+ public void visitAnonymousClass(PsiAnonymousClass aClass) {}
@Override
public void visitElement(PsiElement element) {
@@ -350,16 +410,57 @@
}
@Override
- public void visitReturnStatement(
- PsiReturnStatement statement) {
- PsiExpression value = statement.getReturnValue();
- value = PsiUtil.deparenthesizeExpression(value);
- if (value instanceof PsiReferenceExpression) {
- final PsiReferenceExpression referenceExpression =
- (PsiReferenceExpression)value;
+ public void visitReturnStatement(PsiReturnStatement statement) {
+ final PsiExpression value = PsiUtil.deparenthesizeExpression(statement.getReturnValue());
+ if (!(value instanceof PsiReferenceExpression)) {
+ return;
+ }
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)value;
+ final PsiElement target = referenceExpression.resolve();
+ if (boundVariable.equals(target)) {
+ escaped = true;
+ }
+ }
+
+ @Override
+ public void visitAssignmentExpression(PsiAssignmentExpression expression) {
+ final PsiExpression rhs = PsiUtil.deparenthesizeExpression(expression.getRExpression());
+ if (!(rhs instanceof PsiReferenceExpression)) {
+ return;
+ }
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)rhs;
+ final PsiElement target = referenceExpression.resolve();
+ if (!boundVariable.equals(target)) {
+ return;
+ }
+ final PsiExpression lhs = PsiUtil.deparenthesizeExpression(expression.getLExpression());
+ if (!(lhs instanceof PsiReferenceExpression)) {
+ return;
+ }
+ final PsiReferenceExpression lReferenceExpression = (PsiReferenceExpression)lhs;
+ final PsiElement lTarget = lReferenceExpression.resolve();
+ if (lTarget instanceof PsiField) {
+ escaped = true;
+ }
+ }
+
+ @Override
+ public void visitCallExpression(PsiCallExpression callExpression) {
+ final PsiExpressionList argumentList = callExpression.getArgumentList();
+ if (argumentList == null) {
+ return;
+ }
+ final PsiExpression[] expressions = argumentList.getExpressions();
+ for (PsiExpression expression : expressions) {
+ final PsiExpression expression1 = PsiUtil.deparenthesizeExpression(expression);
+ if (!(expression1 instanceof PsiReferenceExpression)) {
+ continue;
+ }
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression1;
final PsiElement target = referenceExpression.resolve();
- if (target != null && target.equals(boundVariable)) {
+ if (boundVariable.equals(target)) {
escaped = true;
+ break;
}
}
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/SocketResourceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/SocketResourceInspection.java
index 48336cc..b5e2c73 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/SocketResourceInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/SocketResourceInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,21 +15,17 @@
*/
package com.siyeh.ig.resources;
-import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
-import com.intellij.psi.*;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiMethodCallExpression;
+import com.intellij.psi.PsiNewExpression;
+import com.intellij.psi.PsiReferenceExpression;
import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
-
public class SocketResourceInspection extends ResourceInspection {
- @SuppressWarnings({"PublicField"})
- public boolean insideTryAllowed = false;
-
@Override
@NotNull
public String getID() {
@@ -39,103 +35,27 @@
@Override
@NotNull
public String getDisplayName() {
- return InspectionGadgetsBundle.message(
- "socket.opened.not.closed.display.name");
+ return InspectionGadgetsBundle.message("socket.opened.not.closed.display.name");
}
@Override
- @NotNull
- public String buildErrorString(Object... infos) {
- final PsiExpression expression = (PsiExpression)infos[0];
- final PsiType type = expression.getType();
- assert type != null;
- final String text = type.getPresentableText();
- return InspectionGadgetsBundle.message(
- "resource.opened.not.closed.problem.descriptor", text);
- }
-
- @Override
- public JComponent createOptionsPanel() {
- return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message(
- "allow.resource.to.be.opened.inside.a.try.block"),
- this, "insideTryAllowed");
- }
-
-
- @Override
- public BaseInspectionVisitor buildVisitor() {
- return new SocketResourceVisitor();
- }
-
- private class SocketResourceVisitor extends BaseInspectionVisitor {
-
- @Override
- public void visitMethodCallExpression(
- @NotNull PsiMethodCallExpression expression) {
- super.visitMethodCallExpression(expression);
- if (!isSocketFactoryMethod(expression)) {
- return;
- }
- final PsiElement parent = getExpressionParent(expression);
- if (parent instanceof PsiReturnStatement ||
- parent instanceof PsiResourceVariable) {
- return;
- }
- final PsiVariable boundVariable = getVariable(parent);
- if (isSafelyClosed(boundVariable, expression, insideTryAllowed)) {
- return;
- }
- if (isResourceEscapedFromMethod(boundVariable, expression)) {
- return;
- }
- registerError(expression, expression);
- }
-
- @Override
- public void visitNewExpression(
- @NotNull PsiNewExpression expression) {
- super.visitNewExpression(expression);
- if (!isSocketResource(expression)) {
- return;
- }
- final PsiElement parent = getExpressionParent(expression);
- if (parent instanceof PsiReturnStatement ||
- parent instanceof PsiResourceVariable) {
- return;
- }
- final PsiVariable boundVariable = getVariable(parent);
- if (isSafelyClosed(boundVariable, expression, insideTryAllowed)) {
- return;
- }
- if (isResourceEscapedFromMethod(boundVariable, expression)) {
- return;
- }
- registerError(expression, expression);
- }
-
- private boolean isSocketResource(PsiNewExpression expression) {
- return TypeUtils.expressionHasTypeOrSubtype(expression,
- "java.net.Socket",
- "java.net.DatagramSocket",
- "java.net.ServerSocket") != null;
- }
-
- private boolean isSocketFactoryMethod(
- PsiMethodCallExpression expression) {
- final PsiReferenceExpression methodExpression =
- expression.getMethodExpression();
- @NonNls final String methodName =
- methodExpression.getReferenceName();
+ protected boolean isResourceCreation(PsiExpression expression) {
+ if (expression instanceof PsiMethodCallExpression) {
+ final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
+ final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
+ @NonNls final String methodName = methodExpression.getReferenceName();
if (!"accept".equals(methodName)) {
return false;
}
- final PsiExpression qualifier =
- methodExpression.getQualifierExpression();
- if (qualifier == null) {
+ final PsiExpression qualifier = methodExpression.getQualifierExpression();
+ if (qualifier == null || !TypeUtils.expressionHasTypeOrSubtype(qualifier, "java.net.ServerSocket")) {
return false;
}
- return TypeUtils.expressionHasTypeOrSubtype(qualifier,
- "java.net.ServerSocket");
+ return TypeUtils.expressionHasTypeOrSubtype(methodCallExpression, "java.net.Socket");
}
+ else if (expression instanceof PsiNewExpression) {
+ return TypeUtils.expressionHasTypeOrSubtype(expression, "java.net.Socket", "java.net.DatagramSocket", "java.net.ServerSocket") != null;
+ }
+ return false;
}
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/NonSerializableWithSerialVersionUIDFieldInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/NonSerializableWithSerialVersionUIDFieldInspection.java
index b6f45ec..9a1d7ca 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/NonSerializableWithSerialVersionUIDFieldInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/NonSerializableWithSerialVersionUIDFieldInspection.java
@@ -82,6 +82,11 @@
}
private static class RemoveSerialVersionUIDFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerialVersionUIDNotStaticFinalInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerialVersionUIDNotStaticFinalInspection.java
index 481f6a0..8edd146 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerialVersionUIDNotStaticFinalInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerialVersionUIDNotStaticFinalInspection.java
@@ -66,6 +66,11 @@
return InspectionGadgetsBundle.message(
"serialversionuid.private.static.final.long.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/TransientFieldInNonSerializableClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/TransientFieldInNonSerializableClassInspection.java
index c593463..6ed5a82 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/TransientFieldInNonSerializableClassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/TransientFieldInNonSerializableClassInspection.java
@@ -56,6 +56,11 @@
private static class TransientFieldInNonSerializableClassFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/CStyleArrayDeclarationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/CStyleArrayDeclarationInspection.java
index 1e3498d..e4e9168 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/CStyleArrayDeclarationInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/CStyleArrayDeclarationInspection.java
@@ -58,6 +58,11 @@
return InspectionGadgetsBundle.message(
"c.style.array.declaration.replace.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/CallToStringConcatCanBeReplacedByOperatorInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/CallToStringConcatCanBeReplacedByOperatorInspection.java
index f5ed627..5113ab2 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/CallToStringConcatCanBeReplacedByOperatorInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/CallToStringConcatCanBeReplacedByOperatorInspection.java
@@ -67,6 +67,12 @@
return InspectionGadgetsBundle.message("call.to.string.concat.can.be.replaced.by.operator.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ConstantOnLHSOfComparisonInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ConstantOnLHSOfComparisonInspection.java
index 858d5a8..d983cda 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ConstantOnLHSOfComparisonInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ConstantOnLHSOfComparisonInspection.java
@@ -67,6 +67,12 @@
return InspectionGadgetsBundle.message("flip.comparison.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiBinaryExpression expression = (PsiBinaryExpression)descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ConstantOnRHSOfComparisonInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ConstantOnRHSOfComparisonInspection.java
index 4528fef..b0814a5 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ConstantOnRHSOfComparisonInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ConstantOnRHSOfComparisonInspection.java
@@ -60,6 +60,11 @@
}
private static class SwapComparisonFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java
index 605430c..e4ea3d0 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java
@@ -56,6 +56,11 @@
return InspectionGadgetsBundle.message(
"control.flow.statement.without.braces.add.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/EqualsCalledOnEnumConstantInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/EqualsCalledOnEnumConstantInspection.java
index a134ce56..ca343d0 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/EqualsCalledOnEnumConstantInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/EqualsCalledOnEnumConstantInspection.java
@@ -55,6 +55,11 @@
}
private static class EqualsCalledOnEnumValueFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ExtendsObjectInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ExtendsObjectInspection.java
index c3c5955..a87a6c8 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ExtendsObjectInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ExtendsObjectInspection.java
@@ -57,6 +57,11 @@
}
private static class ExtendsObjectFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ImplicitCallToSuperInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ImplicitCallToSuperInspection.java
index f89babe..46195aa 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ImplicitCallToSuperInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ImplicitCallToSuperInspection.java
@@ -70,6 +70,12 @@
"implicit.call.to.super.make.explicit.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ListIndexOfReplaceableByContainsInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ListIndexOfReplaceableByContainsInspection.java
index 63db6c4c..ba1ae8d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ListIndexOfReplaceableByContainsInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ListIndexOfReplaceableByContainsInspection.java
@@ -73,6 +73,11 @@
private static class IndexOfReplaceableByContainsFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/LiteralAsArgToStringEqualsInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/LiteralAsArgToStringEqualsInspection.java
index 04a654b..3da1133 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/LiteralAsArgToStringEqualsInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/LiteralAsArgToStringEqualsInspection.java
@@ -59,6 +59,11 @@
}
private static class SwapEqualsFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/MissortedModifiersInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/MissortedModifiersInspection.java
index 37a7698..4708886 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/MissortedModifiersInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/MissortedModifiersInspection.java
@@ -71,6 +71,11 @@
}
private static class SortModifiersFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/RedundantFieldInitializationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/RedundantFieldInitializationInspection.java
index 2f3cae8..4bd27f0 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/RedundantFieldInitializationInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/RedundantFieldInitializationInspection.java
@@ -67,6 +67,12 @@
return InspectionGadgetsBundle.message("redundant.field.initialization.remove.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
descriptor.getPsiElement().delete();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/RedundantImplementsInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/RedundantImplementsInspection.java
index a54717a..f5281c3 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/RedundantImplementsInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/RedundantImplementsInspection.java
@@ -72,6 +72,11 @@
}
private static class RedundantImplementsFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/SimplifiableAnnotationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/SimplifiableAnnotationInspection.java
index 8028686..0018131 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/SimplifiableAnnotationInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/SimplifiableAnnotationInspection.java
@@ -63,6 +63,11 @@
return InspectionGadgetsBundle.message(
"simplifiable.annotation.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java
index 6f21ec2..0d08682 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java
@@ -78,6 +78,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace with 'String'";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/TypeParameterExtendsObjectInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/TypeParameterExtendsObjectInspection.java
index 58e0661..b80a74a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/TypeParameterExtendsObjectInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/TypeParameterExtendsObjectInspection.java
@@ -75,6 +75,12 @@
"extends.object.remove.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(@NotNull Project project,
ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnclearBinaryExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnclearBinaryExpressionInspection.java
index 9f6d515..dd81762 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnclearBinaryExpressionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnclearBinaryExpressionInspection.java
@@ -51,6 +51,11 @@
}
private static class UnclearBinaryExpressionFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@NotNull
@Override
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedInnerClassAccessInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedInnerClassAccessInspection.java
index dfa79a4..226a745 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedInnerClassAccessInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedInnerClassAccessInspection.java
@@ -70,6 +70,11 @@
private static class UnnecessarilyQualifiedInnerClassAccessFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedStaticUsageInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedStaticUsageInspection.java
index a103093..1339a6d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedStaticUsageInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedStaticUsageInspection.java
@@ -93,6 +93,12 @@
return InspectionGadgetsBundle.message("unnecessary.qualifier.for.this.remove.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedStaticallyImportedElementInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedStaticallyImportedElementInspection.java
index 8f6f9e7..09bcd89 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedStaticallyImportedElementInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarilyQualifiedStaticallyImportedElementInspection.java
@@ -58,6 +58,11 @@
public String getName() {
return InspectionGadgetsBundle.message("unnecessarily.qualified.statically.imported.element.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryBlockStatementInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryBlockStatementInspection.java
index 5af4d22..cd22119 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryBlockStatementInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryBlockStatementInspection.java
@@ -81,6 +81,12 @@
"unnecessary.code.block.unwrap.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryCallToStringValueOfInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryCallToStringValueOfInspection.java
index 62a4ac7..8b6091e 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryCallToStringValueOfInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryCallToStringValueOfInspection.java
@@ -80,6 +80,12 @@
return InspectionGadgetsBundle.message("unnecessary.call.to.string.valueof.quickfix", replacementText);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Simplify";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryConstantArrayCreationExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryConstantArrayCreationExpressionInspection.java
index 3051092..f14138f 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryConstantArrayCreationExpressionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryConstantArrayCreationExpressionInspection.java
@@ -51,6 +51,11 @@
private static class UnnecessaryConstantArrayCreationExpressionFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryConstructorInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryConstructorInspection.java
index 615195a..6416656 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryConstructorInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryConstructorInspection.java
@@ -84,6 +84,12 @@
"unnecessary.constructor.remove.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryEnumModifierInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryEnumModifierInspection.java
index 59df48e..f4bf9ea 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryEnumModifierInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryEnumModifierInspection.java
@@ -70,6 +70,12 @@
return m_name;
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Remove unnecessary modifiers";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryInterfaceModifierInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryInterfaceModifierInspection.java
index 0b905ee..880d3dd 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryInterfaceModifierInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryInterfaceModifierInspection.java
@@ -100,6 +100,12 @@
return InspectionGadgetsBundle.message("smth.unnecessary.remove.quickfix", modifiersText);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Remove unnecessary modifiers";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryParenthesesInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryParenthesesInspection.java
index 2d31641..16dcce5 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryParenthesesInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryParenthesesInspection.java
@@ -73,6 +73,11 @@
public String getName() {
return InspectionGadgetsBundle.message("unnecessary.parentheses.remove.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryQualifierForThisInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryQualifierForThisInspection.java
index 75abe2a..ae6faa9 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryQualifierForThisInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryQualifierForThisInspection.java
@@ -64,6 +64,12 @@
"unnecessary.qualifier.for.this.remove.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarySemicolonInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarySemicolonInspection.java
index 9612996..5c01490 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarySemicolonInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarySemicolonInspection.java
@@ -20,6 +20,7 @@
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
@@ -60,6 +61,11 @@
}
private static class UnnecessarySemicolonFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
@@ -88,30 +94,28 @@
}
}
- private static class UnnecessarySemicolonVisitor
- extends BaseInspectionVisitor {
-
- /**
- * Finds semicolons between the top level classes in a java file.
- */
+ private static class UnnecessarySemicolonVisitor extends BaseInspectionVisitor {
@Override
public void visitFile(PsiFile file) {
- final PsiElement firstChild = file.getFirstChild();
- PsiElement sibling = skipForwardWhiteSpacesAndComments(firstChild);
- while (sibling != null) {
- if (sibling instanceof PsiJavaToken) {
- final PsiJavaToken token = (PsiJavaToken)sibling;
- final IElementType tokenType = token.getTokenType();
- if (tokenType.equals(JavaTokenType.SEMICOLON)) {
- registerError(sibling);
- }
- }
- sibling = skipForwardWhiteSpacesAndComments(sibling);
- }
+ findTopLevelSemicolons(file);
super.visitFile(file);
}
@Override
+ public void visitImportList(PsiImportList list) {
+ findTopLevelSemicolons(list);
+ super.visitImportList(list);
+ }
+
+ private void findTopLevelSemicolons(PsiElement element) {
+ for (PsiElement sibling = element.getFirstChild(); sibling != null; sibling = skipForwardWhiteSpacesAndComments(sibling)) {
+ if (PsiUtil.isJavaToken(sibling, JavaTokenType.SEMICOLON)) {
+ registerError(sibling);
+ }
+ }
+ }
+
+ @Override
public void visitClass(@NotNull PsiClass aClass) {
super.visitClass(aClass);
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarySuperConstructorInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarySuperConstructorInspection.java
index 8cfac92..83c70a1 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarySuperConstructorInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarySuperConstructorInspection.java
@@ -56,6 +56,11 @@
private static class UnnecessarySuperConstructorFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarySuperQualifierInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarySuperQualifierInspection.java
index 1a86985..fea9d87 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarySuperQualifierInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessarySuperQualifierInspection.java
@@ -57,6 +57,11 @@
extends InspectionGadgetsFix {
@Override
@NotNull
+ public String getFamilyName() {
+ return getName();
+ }
+ @Override
+ @NotNull
public String getName() {
return InspectionGadgetsBundle.message(
"unnecessary.super.qualifier.quickfix");
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryThisInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryThisInspection.java
index e7413de..b5a4f53 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryThisInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryThisInspection.java
@@ -70,6 +70,12 @@
return InspectionGadgetsBundle.message("unnecessary.this.remove.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement thisToken = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryToStringCallInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryToStringCallInspection.java
index d8831d7..1d2a26d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryToStringCallInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryToStringCallInspection.java
@@ -74,6 +74,12 @@
return InspectionGadgetsBundle.message("unnecessary.call.to.string.valueof.quickfix", replacementText);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Simplify";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)descriptor.getPsiElement().getParent().getParent();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedStaticUsageInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedStaticUsageInspection.java
index 65b863d..5a7d421 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedStaticUsageInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedStaticUsageInspection.java
@@ -118,6 +118,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Qualify static access";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/ConditionSignalInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/ConditionSignalInspection.java
index ebef230..290aefe 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/ConditionSignalInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/ConditionSignalInspection.java
@@ -67,6 +67,12 @@
"condition.signal.replace.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/DoubleCheckedLockingInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/DoubleCheckedLockingInspection.java
index f65b176..0036f4a4 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/DoubleCheckedLockingInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/DoubleCheckedLockingInspection.java
@@ -87,6 +87,12 @@
"double.checked.locking.quickfix", field.getName());
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Make field volatile";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/MethodMayBeSynchronizedInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/MethodMayBeSynchronizedInspection.java
index a8846a7..ba20b19 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/MethodMayBeSynchronizedInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/MethodMayBeSynchronizedInspection.java
@@ -64,6 +64,12 @@
"method.may.be.synchronized.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/ObjectNotifyInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/ObjectNotifyInspection.java
index 3468a3a..d7127fc 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/ObjectNotifyInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/ObjectNotifyInspection.java
@@ -58,6 +58,11 @@
}
private static class ObjectNotifyFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/SynchronizedMethodInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/SynchronizedMethodInspection.java
index 993073b..6c916b7 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/SynchronizedMethodInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/SynchronizedMethodInspection.java
@@ -86,6 +86,11 @@
return InspectionGadgetsBundle.message(
"synchronized.method.move.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/ThreadRunInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/ThreadRunInspection.java
index 47707b4..c25a23b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/ThreadRunInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/ThreadRunInspection.java
@@ -62,6 +62,12 @@
"thread.run.replace.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(@NotNull Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/AmbiguousFieldAccessInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/AmbiguousFieldAccessInspection.java
index 504f71d..26d6684 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/AmbiguousFieldAccessInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/AmbiguousFieldAccessInspection.java
@@ -68,6 +68,12 @@
return InspectionGadgetsBundle.message("ambiguous.field.access.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/AmbiguousMethodCallInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/AmbiguousMethodCallInspection.java
index 5e072c3..c2f335f 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/AmbiguousMethodCallInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/AmbiguousMethodCallInspection.java
@@ -56,6 +56,11 @@
public String getName() {
return InspectionGadgetsBundle.message("ambiguous.method.call.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/abstraction/StaticMethodOnlyUsedInOneClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/abstraction/StaticMethodOnlyUsedInOneClassInspection.java
index 0688918..c59f7e5 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/abstraction/StaticMethodOnlyUsedInOneClassInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/abstraction/StaticMethodOnlyUsedInOneClassInspection.java
@@ -54,6 +54,11 @@
public String getName() {
return InspectionGadgetsBundle.message("static.method.only.used.in.one.class.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(@NotNull final Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ProtectedMemberInFinalClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ProtectedMemberInFinalClassInspection.java
index 02562bb..7eeeaee 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ProtectedMemberInFinalClassInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ProtectedMemberInFinalClassInspection.java
@@ -70,6 +70,11 @@
}
private static class MakePrivateFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/PublicConstructorInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/PublicConstructorInspection.java
index 9ef67e9..400dc80 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/PublicConstructorInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/PublicConstructorInspection.java
@@ -77,6 +77,12 @@
return InspectionGadgetsBundle.message("public.constructor.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(final Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiClass.class, PsiMethod.class);
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/UtilityClassWithoutPrivateConstructorInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/UtilityClassWithoutPrivateConstructorInspection.java
index d524ae2..277192e 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/UtilityClassWithoutPrivateConstructorInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/UtilityClassWithoutPrivateConstructorInspection.java
@@ -106,6 +106,12 @@
return InspectionGadgetsBundle.message("utility.class.without.private.constructor.create.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement classNameIdentifier = descriptor.getPsiElement();
@@ -145,6 +151,11 @@
}
private static class MakeConstructorPrivateFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/BooleanVariableAlwaysNegatedInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/BooleanVariableAlwaysNegatedInspection.java
index 575f65d..1a69c90 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/BooleanVariableAlwaysNegatedInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/BooleanVariableAlwaysNegatedInspection.java
@@ -18,16 +18,11 @@
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
-import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.invertBoolean.InvertBooleanDialog;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspection;
-import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
-import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
public class BooleanVariableAlwaysNegatedInspection extends BooleanVariableAlwaysNegatedInspectionBase {
@@ -54,6 +49,12 @@
"boolean.variable.always.inverted.quickfix", name);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Invert";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/ReuseOfLocalVariableInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/ReuseOfLocalVariableInspection.java
index 89a3762..024c0df 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/ReuseOfLocalVariableInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/ReuseOfLocalVariableInspection.java
@@ -23,19 +23,14 @@
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Query;
import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspection;
-import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.HighlightUtils;
-import com.siyeh.ig.psiutils.VariableAccessUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
@@ -57,6 +52,12 @@
"reuse.of.local.variable.split.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/TooBroadScopeInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/TooBroadScopeInspection.java
index 404e2b7..b4a6699 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/TooBroadScopeInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/TooBroadScopeInspection.java
@@ -54,6 +54,12 @@
return InspectionGadgetsBundle.message("too.broad.scope.narrow.quickfix", variableName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Narrow scope";
+ }
+
@Override
protected void doFix(@NotNull Project project, ProblemDescriptor descriptor) {
final PsiElement variableIdentifier = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/encapsulation/ReturnOfCollectionFieldInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/encapsulation/ReturnOfCollectionFieldInspection.java
index b2845eb..50923d3 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/encapsulation/ReturnOfCollectionFieldInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/encapsulation/ReturnOfCollectionFieldInspection.java
@@ -68,6 +68,12 @@
myQualifiedClassName = qualifiedClassName;
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Make return collection 'unmodifiable'";
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/ThrowsRuntimeExceptionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/ThrowsRuntimeExceptionInspection.java
index e09265b..c35f3ee 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/ThrowsRuntimeExceptionInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/ThrowsRuntimeExceptionInspection.java
@@ -75,6 +75,12 @@
return InspectionGadgetsBundle.message("throws.runtime.exception.move.quickfix", myExceptionName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Move to Javadoc '@throws'";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
@@ -166,6 +172,12 @@
return InspectionGadgetsBundle.message("throws.runtime.exception.quickfix", myClassName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Remove from \"throws\" clause";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
descriptor.getPsiElement().delete();
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/TooBroadCatchInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/TooBroadCatchInspection.java
index 2df05e5..2fba528 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/TooBroadCatchInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/TooBroadCatchInspection.java
@@ -116,6 +116,12 @@
return InspectionGadgetsBundle.message("too.broad.catch.quickfix", myText);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Add 'catch' clause";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement typeElement = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/EncapsulateVariableFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/EncapsulateVariableFix.java
index 3e32290..59461ca 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/EncapsulateVariableFix.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/EncapsulateVariableFix.java
@@ -42,6 +42,12 @@
fieldName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Encapsulate field";
+ }
+
@Override
public void doFix(final Project project, ProblemDescriptor descriptor) {
final PsiElement nameElement = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/ExtractMethodFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/ExtractMethodFix.java
index fe23fd7..8d09ff2 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/ExtractMethodFix.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/ExtractMethodFix.java
@@ -36,6 +36,12 @@
return InspectionGadgetsBundle.message("extract.method.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(final Project project, ProblemDescriptor descriptor) {
final PsiExpression expression =
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/InlineCallFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/InlineCallFix.java
index dcdb958..43e5774 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/InlineCallFix.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/InlineCallFix.java
@@ -28,6 +28,11 @@
import org.jetbrains.annotations.NotNull;
public class InlineCallFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/InlineVariableFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/InlineVariableFix.java
index 5bdf57b..79fa474 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/InlineVariableFix.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/InlineVariableFix.java
@@ -29,6 +29,11 @@
import java.util.Collection;
public class InlineVariableFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/IntroduceConstantFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/IntroduceConstantFix.java
index bb0692b..c4d4df5 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/IntroduceConstantFix.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/IntroduceConstantFix.java
@@ -29,6 +29,11 @@
import org.jetbrains.annotations.NotNull;
public class IntroduceConstantFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/IntroduceVariableFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/IntroduceVariableFix.java
index 36ba905..34980b7 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/IntroduceVariableFix.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/IntroduceVariableFix.java
@@ -53,6 +53,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return InspectionGadgetsBundle.message("introduce.variable.quickfix");
+ }
+
@Nullable
public PsiExpression getExpressionToExtract(PsiElement element) {
return PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class, false);
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/MakeClassFinalFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/MakeClassFinalFix.java
index 9691da4..6181adc 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/MakeClassFinalFix.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/MakeClassFinalFix.java
@@ -53,6 +53,12 @@
"make.class.final.fix.name", className);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Make class final";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/MoveAnonymousToInnerClassFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/MoveAnonymousToInnerClassFix.java
index bd41131..e6e98a4 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/MoveAnonymousToInnerClassFix.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/MoveAnonymousToInnerClassFix.java
@@ -30,6 +30,8 @@
public class MoveAnonymousToInnerClassFix extends InspectionGadgetsFix {
+ public static final String NAME = InspectionGadgetsBundle.message(
+ "move.anonymous.to.inner.quickfix");
private final String name;
public MoveAnonymousToInnerClassFix(String name) {
@@ -37,8 +39,13 @@
}
public MoveAnonymousToInnerClassFix() {
- name = InspectionGadgetsBundle.message(
- "move.anonymous.to.inner.quickfix");
+ name = NAME;
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return NAME;
}
@Override
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/MoveClassFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/MoveClassFix.java
index 2e56487..101a6c6 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/MoveClassFix.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/MoveClassFix.java
@@ -30,6 +30,11 @@
import org.jetbrains.annotations.NotNull;
public class MoveClassFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/RenameFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/RenameFix.java
index 009dc19..30889e5 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/RenameFix.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/RenameFix.java
@@ -51,6 +51,12 @@
m_searchInNonJavaFiles = searchInNonJavaFiles;
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return InspectionGadgetsBundle.message("rename.quickfix");
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/RenameParameterFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/RenameParameterFix.java
index 1a99ce0..4397030 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/RenameParameterFix.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/RenameParameterFix.java
@@ -39,6 +39,12 @@
return InspectionGadgetsBundle.message("renameto.quickfix", m_targetName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Rename";
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement nameIdentifier = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/ReplaceInheritanceWithDelegationFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/ReplaceInheritanceWithDelegationFix.java
index 9538ded..df1a2e4 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/ReplaceInheritanceWithDelegationFix.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/ReplaceInheritanceWithDelegationFix.java
@@ -37,6 +37,11 @@
return InspectionGadgetsBundle.message(
"replace.inheritance.with.delegation.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(@NotNull final Project project, ProblemDescriptor descriptor) {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java
index 167e800..5defb34 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java
@@ -106,6 +106,11 @@
public String getName() {
return InspectionGadgetsBundle.message("static.import.replace.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/inheritance/StaticInheritanceFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/inheritance/StaticInheritanceFix.java
index e1a0320..ce49dd8 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/inheritance/StaticInheritanceFix.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/inheritance/StaticInheritanceFix.java
@@ -62,6 +62,12 @@
return InspectionGadgetsBundle.message("static.inheritance.replace.quickfix", scope);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace inheritance with qualified reference";
+ }
+
@Override
public void doFix(final Project project, final ProblemDescriptor descriptor) throws IncorrectOperationException {
ApplicationManager.getApplication().invokeLater(new Runnable() {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/OverridableMethodCallDuringObjectConstructionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/OverridableMethodCallDuringObjectConstructionInspection.java
index a7ee6cd..f1b36bf 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/OverridableMethodCallDuringObjectConstructionInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/OverridableMethodCallDuringObjectConstructionInspection.java
@@ -79,6 +79,12 @@
return InspectionGadgetsBundle.message("make.method.final.fix.name", methodName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Make method final";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement methodName = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/javadoc/PackageDotHtmlMayBePackageInfoInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/javadoc/PackageDotHtmlMayBePackageInfoInspection.java
index 2b8b78a..e7ac10a 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/javadoc/PackageDotHtmlMayBePackageInfoInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/javadoc/PackageDotHtmlMayBePackageInfoInspection.java
@@ -79,6 +79,12 @@
return InspectionGadgetsBundle.message("package.dot.html.may.be.package.info.delete.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
@@ -107,6 +113,11 @@
public PackageDotHtmlMayBePackageInfoFix(String aPackage) {
this.aPackage = aPackage;
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/BeforeClassOrAfterClassIsPublicStaticVoidNoArgInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/BeforeClassOrAfterClassIsPublicStaticVoidNoArgInspection.java
index 261947b..261f1a9 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/BeforeClassOrAfterClassIsPublicStaticVoidNoArgInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/BeforeClassOrAfterClassIsPublicStaticVoidNoArgInspection.java
@@ -131,6 +131,12 @@
}
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Fix modifiers";
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4AnnotatedMethodInJUnit3TestCaseInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4AnnotatedMethodInJUnit3TestCaseInspection.java
index 3a20613..be71c41 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4AnnotatedMethodInJUnit3TestCaseInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/JUnit4AnnotatedMethodInJUnit3TestCaseInspection.java
@@ -126,6 +126,12 @@
return InspectionGadgetsBundle.message("convert.junit3.test.class.quickfix", className);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Convert JUnit 3 class to JUnit 4";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
@@ -254,6 +260,11 @@
}
private static class RemoveTestAnnotationFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/ParameterizedParametersStaticCollectionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/ParameterizedParametersStaticCollectionInspection.java
index 94b3d3d..dc7fc4c 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/ParameterizedParametersStaticCollectionInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/ParameterizedParametersStaticCollectionInspection.java
@@ -149,6 +149,12 @@
public String getName() {
return infos.length > 0 ? (String)infos[0] : "Create @Parameterized.Parameters data provider";
}
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Fix data provider signature";
+ }
};
}
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/UseOfObsoleteAssertInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/UseOfObsoleteAssertInspection.java
index 1e1140e..fda763f 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/junit/UseOfObsoleteAssertInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/junit/UseOfObsoleteAssertInspection.java
@@ -225,5 +225,12 @@
public String getName() {
return InspectionGadgetsBundle.message("use.of.obsolete.assert.quickfix");
}
+
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
+
}
}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/logging/LogStatementGuardedByLogConditionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/LogStatementGuardedByLogConditionInspection.java
index b73b3406..c99f05b 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/logging/LogStatementGuardedByLogConditionInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/LogStatementGuardedByLogConditionInspection.java
@@ -102,6 +102,12 @@
private class LogStatementGuardedByLogConditionFix extends InspectionGadgetsFix {
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/logging/LoggerInitializedWithForeignClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/LoggerInitializedWithForeignClassInspection.java
index 18d5932..37619fe 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/logging/LoggerInitializedWithForeignClassInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/LoggerInitializedWithForeignClassInspection.java
@@ -97,6 +97,12 @@
newClassName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace foreign class";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/logging/StringConcatenationArgumentToLogCallInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/StringConcatenationArgumentToLogCallInspection.java
index 5169392..40925af 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/logging/StringConcatenationArgumentToLogCallInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/StringConcatenationArgumentToLogCallInspection.java
@@ -83,6 +83,11 @@
public String getName() {
return InspectionGadgetsBundle.message("string.concatenation.argument.to.log.call.quickfix");
}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/CollectionsFieldAccessReplaceableByMethodCallInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/CollectionsFieldAccessReplaceableByMethodCallInspection.java
index bae94a9..a8b5918 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/CollectionsFieldAccessReplaceableByMethodCallInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/CollectionsFieldAccessReplaceableByMethodCallInspection.java
@@ -69,6 +69,12 @@
replacementText = getCollectionsMethodCallText(referenceName);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace Collections.EMPTY_* with call";
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/EnumerationCanBeIterationInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/EnumerationCanBeIterationInspection.java
index c2f2797..8c371e6 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/EnumerationCanBeIterationInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/EnumerationCanBeIterationInspection.java
@@ -78,6 +78,11 @@
private static class EnumerationCanBeIterationFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/ForCanBeForeachInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/ForCanBeForeachInspection.java
index e2fadba..edfc882 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/ForCanBeForeachInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/ForCanBeForeachInspection.java
@@ -90,6 +90,12 @@
@Override
@NotNull
+ public String getFamilyName() {
+ return getName();
+ }
+
+ @Override
+ @NotNull
public String getName() {
return InspectionGadgetsBundle.message("foreach.replace.quickfix");
}
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/IfCanBeSwitchInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/IfCanBeSwitchInspection.java
index c367688..08ea823 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/IfCanBeSwitchInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/IfCanBeSwitchInspection.java
@@ -151,6 +151,12 @@
myMinimumBranches = minimumBranches;
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/IndexOfReplaceableByContainsInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/IndexOfReplaceableByContainsInspection.java
index 0b7d10c..bd7acc8 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/IndexOfReplaceableByContainsInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/IndexOfReplaceableByContainsInspection.java
@@ -118,6 +118,13 @@
return InspectionGadgetsBundle.message(
"replace.indexof.with.contains.quickfix");
}
+
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
+
}
static String createContainsExpressionText(
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java
index f4ea3c7..175b0ef 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java
@@ -68,6 +68,11 @@
}
private static class MethodCanBeVariableArityMethodFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@NotNull
@Override
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/StringBufferReplaceableByStringBuilderInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/StringBufferReplaceableByStringBuilderInspection.java
index d5a3e81..33b1a94 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/StringBufferReplaceableByStringBuilderInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/StringBufferReplaceableByStringBuilderInspection.java
@@ -94,6 +94,12 @@
return InspectionGadgetsBundle.message("string.buffer.replaceable.by.string.builder.replace.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java
index f7691a0..804a290 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java
@@ -66,6 +66,11 @@
private static class TryFinallyCanBeTryWithResourcesFix extends InspectionGadgetsFix {
public TryFinallyCanBeTryWithResourcesFix() {}
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryWithIdenticalCatchesInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryWithIdenticalCatchesInspection.java
index 84dfad8..865e229 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryWithIdenticalCatchesInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryWithIdenticalCatchesInspection.java
@@ -171,6 +171,12 @@
return InspectionGadgetsBundle.message("try.with.identical.catches.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiCatchSection section = (PsiCatchSection)descriptor.getPsiElement();
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/UnnecessaryBoxingInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/UnnecessaryBoxingInspection.java
index 62cfc32ed..2b1551e 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/UnnecessaryBoxingInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/UnnecessaryBoxingInspection.java
@@ -72,6 +72,11 @@
}
private static class UnnecessaryBoxingFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/UnnecessaryUnboxingInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/UnnecessaryUnboxingInspection.java
index 47f47e9..d3acf7d 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/UnnecessaryUnboxingInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/UnnecessaryUnboxingInspection.java
@@ -89,6 +89,12 @@
"unnecessary.unboxing.remove.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/WhileCanBeForeachInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/WhileCanBeForeachInspection.java
index b659021e..676ab05 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/WhileCanBeForeachInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/WhileCanBeForeachInspection.java
@@ -69,6 +69,11 @@
}
private static class WhileCanBeForeachFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/naming/MethodNameSameAsClassNameInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/naming/MethodNameSameAsClassNameInspection.java
index b3a17c1..09896b6 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/naming/MethodNameSameAsClassNameInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/naming/MethodNameSameAsClassNameInspection.java
@@ -74,6 +74,12 @@
return InspectionGadgetsBundle.message("make.method.ctr.quickfix");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/naming/NonExceptionNameEndsWithExceptionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/naming/NonExceptionNameEndsWithExceptionInspection.java
index 76586bb..fdd4c99 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/naming/NonExceptionNameEndsWithExceptionInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/naming/NonExceptionNameEndsWithExceptionInspection.java
@@ -76,6 +76,12 @@
"non.exception.name.ends.with.exception.quickfix", name);
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Make class extend 'Exception'";
+ }
+
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/DynamicRegexReplaceableByCompiledPatternInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/DynamicRegexReplaceableByCompiledPatternInspection.java
index 8cbe625..213c92e 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/DynamicRegexReplaceableByCompiledPatternInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/DynamicRegexReplaceableByCompiledPatternInspection.java
@@ -72,6 +72,11 @@
}
private static class DynamicRegexReplaceableByCompiledPatternFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/ToArrayCallWithZeroLengthArrayArgumentInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/ToArrayCallWithZeroLengthArrayArgumentInspection.java
index ed3f5bf..7a85f27 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/performance/ToArrayCallWithZeroLengthArrayArgumentInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/performance/ToArrayCallWithZeroLengthArrayArgumentInspection.java
@@ -65,6 +65,11 @@
private static class ToArrayCallWithZeroLengthArrayArgumentFix extends InspectionGadgetsFix {
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/ExternalizableWithoutPublicNoArgConstructorInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/ExternalizableWithoutPublicNoArgConstructorInspection.java
index b46228a..9aa0753 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/ExternalizableWithoutPublicNoArgConstructorInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/ExternalizableWithoutPublicNoArgConstructorInspection.java
@@ -84,6 +84,12 @@
return InspectionGadgetsBundle.message("make.constructor.public");
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/SizeReplaceableByIsEmptyInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/SizeReplaceableByIsEmptyInspection.java
index 2a0ff2c0..e2c4270 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/SizeReplaceableByIsEmptyInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/SizeReplaceableByIsEmptyInspection.java
@@ -84,6 +84,11 @@
private static class SizeReplaceableByIsEmptyFix
extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryFullyQualifiedNameInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryFullyQualifiedNameInspection.java
index 17e8ea6..7f8c724 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryFullyQualifiedNameInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryFullyQualifiedNameInspection.java
@@ -84,6 +84,12 @@
this.inSameFile = inSameFile;
}
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Replace fully qualified name";
+ }
+
@Override
@NotNull
public String getName() {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedInnerClassAccessInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedInnerClassAccessInspection.java
index f005ed0..0308ac4 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedInnerClassAccessInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedInnerClassAccessInspection.java
@@ -64,6 +64,11 @@
}
private static class UnqualifiedInnerClassAccessFix extends InspectionGadgetsFix {
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
@Override
@NotNull
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanParameter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanParameter.html
new file mode 100644
index 0000000..5653cda
--- /dev/null
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/BooleanParameter.html
@@ -0,0 +1,14 @@
+<html>
+<body>
+It's almost always a mistake to add a <b>boolean</b> parameter to a public method (part of an API) if that method is not a setter.
+When reading code using such a method, it can be difficult to decipher what the <b>boolean</b> stands for without looking at
+the source or documentation.
+This problem is also known as <a href="http://ariya.ofilabs.com/2011/08/hall-of-api-shame-boolean-trap.html">the boolean trap</a>.
+The <b>boolean</b> parameter can often be profitably replaced with an <b>enum</b>
+<!-- tooltip end -->
+<p>
+Use the option below to only warn when a method contains more than one boolean parameter.
+<p>
+<small>New in 13</small>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/resources/ChannelResourceInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/resources/ChannelResourceInspection.java
deleted file mode 100644
index c11d447..0000000
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/resources/ChannelResourceInspection.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package com.siyeh.igtest.resources;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.io.*;
-import java.net.Socket;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.net.ServerSocket;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.FileChannel;
-
-public class ChannelResourceInspection {
-
- public void foo2() throws IOException {
- ServerSocket serverSocket = new ServerSocket(1, 1);
- serverSocket.getChannel();
- try {
-
- } finally {
- serverSocket.close();
- }
- }
-
- public void foo3() throws IOException {
- ServerSocket serverSocket = null;
- serverSocket = new ServerSocket(1, 1);
- ServerSocketChannel channel = serverSocket.getChannel();
- try {
- } finally {
- serverSocket.close();
- }
- }
-
- public void foo4() throws IOException {
- ServerSocket serverSocket = null;
- serverSocket = new ServerSocket(1, 1);
- ServerSocketChannel channel = serverSocket.getChannel();
- try {
- channel.close();
- } finally {
- serverSocket.close();
- }
- }
-
- public void foo5() throws IOException {
- ServerSocket serverSocket = null;
- ServerSocketChannel channel = null;
- serverSocket = new ServerSocket(1, 1);
- channel = serverSocket.getChannel();
- try {
- // do stuff
- } finally {
- channel.close();
- serverSocket.close();
- }
- }
-
- public static void copyFile(@NotNull File from, @NotNull File to)
- throws IOException {
- if (from.getCanonicalPath().equals(to.getCanonicalPath()))
- return;
- final FileInputStream inStream = new FileInputStream(from);
- try {
- boolean success = false;
- try {
- final FileOutputStream outStream = new FileOutputStream(to);
- try {
- final FileChannel inChannel = inStream.getChannel();
- try {
- final FileChannel outChannel = outStream.getChannel();
- try {
- inChannel.transferTo(0, inChannel.size(), outChannel);
- }
- finally {
- outChannel.close();
- }
- }
- finally {
- inChannel.close();
- }
- }
- finally {
- outStream.close();
- }
- //copyLastModifiedDate( from, to );
- success = true;
- }
- finally {
- if (!success)
- to.delete();
- }
- }
- finally {
- inStream.close();
- }
- }
-
- public static void copy(FileInputStream source,
- FileOutputStream target)
- throws IOException {
- FileChannel sourceChannel = source.getChannel(); // line 4
- FileChannel targetChannel = target.getChannel(); // line 5
- try {
- sourceChannel.transferTo(0, sourceChannel.size(),
- targetChannel);
- }
- finally {
- try {
- targetChannel.close();
- }
- finally {
- sourceChannel.close();
- }
- }
- }
-
- public static void copyFile2(File source, File target)
- throws IOException {
- final FileInputStream sourceStream = new FileInputStream(source);
- try {
- final FileOutputStream targetStream =
- new FileOutputStream(target);
- try {
- copy(sourceStream, targetStream);
- }
- finally {
- targetStream.close();
- }
- }
- finally {
- sourceStream.close();
- }
- }
-}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/resources/JDBCResourceInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/resources/JDBCResourceInspection.java
deleted file mode 100644
index c00cf70..0000000
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/resources/JDBCResourceInspection.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package com.siyeh.igtest.resources;
-
-import java.sql.*;
-
-public class JDBCResourceInspection {
- private Driver driver;
-
- public void foo() throws SQLException {
- Connection connection = null;
- try {
- connection = driver.connect("foo", null);
- } finally {
- connection.close();
- }
-
- }
-
- public void foo2() throws SQLException {
- Connection connection = null;
- try {
- connection = driver.connect("foo", null);
- } finally {
- }
- }
-
-
- public void foo3() throws SQLException {
- Connection connection = null;
- try {
- connection = driver.connect("foo", null);
- connection.createStatement();
- } finally {
- connection.close();
- }
-
- }
-
- public void foo4() throws SQLException {
- Connection connection = null;
- Statement statement = null;
- try {
- connection = driver.connect("foo", null);
- statement = connection.createStatement();
- } finally {
- connection.close();
- }
-
- }
-
- public void foo5() throws SQLException {
- Connection connection = null;
- Statement statement = null;
- try {
- connection = driver.connect("foo", null);
- statement = connection.createStatement();
- } finally {
- statement.close();
- connection.close();
- }
-
- }
-
- public void foo6() throws SQLException {
- Connection connection = null;
- Statement statement = null;
- try {
- connection = driver.connect("foo", null);
- statement = connection.prepareStatement("foo");
- } finally {
- connection.close();
- }
-
- }
-
- public void foo7() throws SQLException {
- Connection connection = null;
- Statement statement = null;
- try {
- connection = driver.connect("foo", null);
- statement = connection.prepareStatement("foo");
- } finally {
- statement.close();
- connection.close();
- }
-
- }
-
- public void foo8() throws SQLException {
- Connection connection = null;
- Statement statement = null;
- try {
- connection = driver.connect("foo", null);
- statement = connection.prepareCall("foo");
- } finally {
- connection.close();
- }
-
- }
-
- public void foo9() throws SQLException {
- Connection connection = null;
- Statement statement = null;
- try {
- connection = driver.connect("foo", null);
- statement = connection.prepareCall("foo");
- } finally {
- statement.close();
- connection.close();
- }
-
- }
-
- public void foo10() throws SQLException {
- Connection connection = null;
- Statement statement = null;
- ResultSet resultSet = null;
- try {
- connection = driver.connect("foo", null);
- statement = connection.prepareCall("foo");
- resultSet = statement.executeQuery("foo");
- } finally {
- statement.close();
- connection.close();
- }
-
- }
-
- public void foo11() throws SQLException {
- Connection connection = null;
- Statement statement = null;
- ResultSet resultSet = null;
- try {
- connection = driver.connect("foo", null);
- statement = connection.prepareCall("foo");
- resultSet = statement.executeQuery("foo");
- } finally {
- resultSet.close();
- statement.close();
- connection.close();
- }
-
- }
-
-}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/resources/SocketResourceInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/resources/SocketResourceInspection.java
deleted file mode 100644
index a1097c1..0000000
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/resources/SocketResourceInspection.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.siyeh.igtest.resources;
-
-import java.io.*;
-import java.net.Socket;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.net.ServerSocket;
-
-public class SocketResourceInspection {
- public void foo() throws IOException, UnknownHostException {
- new Socket( InetAddress.getLocalHost(), 1);
- }
-
- public void foo2() throws IOException, UnknownHostException {
- final Socket socket = new Socket(InetAddress.getLocalHost(), 1);
- }
-
- public void foo25() throws IOException, UnknownHostException {
- try {
- final Socket socket = new Socket(InetAddress.getLocalHost(), 1);
- } finally {
- }
-
- }
-
-
- public void foo3() throws IOException {
- final Socket socket = new Socket(InetAddress.getLocalHost(), 1);
- socket.close();
- }
-
- public void foo4() throws IOException {
- Socket socket = null;
- try {
- socket = new Socket(InetAddress.getLocalHost(), 1);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- socket.close();
- }
-
- public void foo5() throws IOException {
- Socket socket = null;
- try {
- socket = new Socket(InetAddress.getLocalHost(), 1);
- } finally {
- socket.close();
- }
- }
- public void foo6() throws IOException {
- ServerSocket socket = null;
- try{
- socket = new ServerSocket(1, 1);
- } finally{
- }
- }
- public void foo7() throws IOException {
- ServerSocket serverSocket = null;
- try{
- serverSocket = new ServerSocket(1, 1);
- Socket socket = serverSocket.accept();
- } finally{
- serverSocket.close();
- }
- }
-
-}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/resources/io/plain/IOResourceInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/resources/io/plain/IOResourceInspection.java
index 74481e3..dacea83 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/resources/io/plain/IOResourceInspection.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/resources/io/plain/IOResourceInspection.java
@@ -158,4 +158,24 @@
writer.close();
}
}
+
+ void escaper(InputStream in) {}
+
+ void escaped3() throws FileNotFoundException {
+ escaper(new FileInputStream(""));
+ }
+
+ void escaped4() throws FileNotFoundException {
+ class X {
+ X(InputStream s) {}
+ }
+ new X(new FileInputStream("")) {};
+ InputStream s = new FileInputStream("");
+ new X(s) {};
+ }
+
+ void escaped5() throws FileNotFoundException {
+ InputStream in = new FileInputStream("");
+ escaper(in);
+ }
}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_semicolon/UnnecessarySemicolonInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_semicolon/UnnecessarySemicolonInspection.java
index 13d978b4..67524e4 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_semicolon/UnnecessarySemicolonInspection.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unnecessary_semicolon/UnnecessarySemicolonInspection.java
@@ -1,6 +1,6 @@
package com.siyeh.igtest.style.unnecessary_semicolon;;
-;
+import java.util.List;;
public class UnnecessarySemicolonInspection
{
int i;
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
index a76eb23..6f56e02 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
@@ -47,6 +47,14 @@
myFixture.addClass(classText);
}
+ protected final void doStatementTest(@Language(value="JAVA", prefix="class X { void m() {", suffix="}}") @NotNull @NonNls String statementText) {
+ doTest("class X { void m() {" + statementText + "}}");
+ }
+
+ protected final void doMemberTest(@Language(value="JAVA", prefix="class X {", suffix="}") @NotNull @NonNls String memberText) {
+ doTest("class X {" + memberText + "}");
+ }
+
protected final void doTest(@Language("JAVA") @NotNull @NonNls String classText) {
@NonNls final StringBuilder newText = new StringBuilder();
int start = 0;
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/BooleanParameterInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/BooleanParameterInspectionTest.java
new file mode 100644
index 0000000..4860377
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/BooleanParameterInspectionTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.siyeh.ig.abstraction;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.siyeh.ig.LightInspectionTestCase;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class BooleanParameterInspectionTest extends LightInspectionTestCase {
+
+ public void testSimple() {
+ doTest("class X {" +
+ " public void /*'public' method 'm' with 'boolean' parameter*/m/**/(boolean b) {}" +
+ " public void n() {}" +
+ " public void o(int i) {}" +
+ " void p(boolean b) {}" +
+ "}");
+ }
+
+ @Override
+ protected LocalInspectionTool getInspection() {
+ return new BooleanParameterInspection();
+ }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/controlflow/ForLoopWithMissingComponentInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/controlflow/ForLoopWithMissingComponentInspectionTest.java
new file mode 100644
index 0000000..71af30e
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/controlflow/ForLoopWithMissingComponentInspectionTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.siyeh.ig.controlflow;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.siyeh.ig.LightInspectionTestCase;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class ForLoopWithMissingComponentInspectionTest extends LightInspectionTestCase {
+
+ public void testMissingAllComponents() {
+ doStatementTest("/*'for' statement lacks initializer, condition and update*/for/**/ (;;) {}");
+ }
+
+ public void testMissingConditionAndUpdate() {
+ doStatementTest("/*'for' statement lacks condition and update*/for/**/ (int i = 0;;);");
+ }
+
+ public void testMissingInitializationAndUpdate() {
+ doStatementTest("/*'for' statement lacks initializer and update*/for/**/ (;true;);");
+ }
+
+ public void testMissingCondition() {
+ doStatementTest("/*'for' statement lacks condition*/for/**/ (int i = 0;;i++);");
+ }
+
+ public void testCorrect() {
+ doStatementTest("for(int i = 0;true;i++);");
+ }
+
+ public void testIterator() {
+ doMemberTest("void m(java.util.List l) {" +
+ " for (java.util.ListIterator it = l.listIterator(); it.hasNext();) {" +
+ " System.out.println(it.next());" +
+ " }" +
+ "}");
+ }
+
+ @Override
+ protected LocalInspectionTool getInspection() {
+ final ForLoopWithMissingComponentInspection inspection = new ForLoopWithMissingComponentInspection();
+ inspection.ignoreCollectionLoops = true;
+ return inspection;
+ }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/ChannelResourceInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/ChannelResourceInspectionTest.java
new file mode 100644
index 0000000..af6ade7
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/ChannelResourceInspectionTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.siyeh.ig.resources;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.siyeh.ig.LightInspectionTestCase;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class ChannelResourceInspectionTest extends LightInspectionTestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ addEnvironmentClass("package java.nio.channels;" +
+ "public interface Channel extends java.io.Closeable {}");
+ addEnvironmentClass("package java.nio.channels;" +
+ "public interface FileChannel extends Channel {}");
+ addEnvironmentClass("package java.net;" +
+ "import java.nio.channels.FileChannel;" +
+ "public class SocketInputStream implements java.io.Closeable {" +
+ " public FileChannel getChannel() {" +
+ " return null;" +
+ " }" +
+ " public void close() throws IOException {}" +
+ "}");
+ }
+
+ public void testFactoryClosed() {
+ doTest("import java.net.*;" +
+ "import java.io.*;" +
+ "class X {" +
+ " void m() throws IOException {" +
+ " SocketInputStream ss = new SocketInputStream();" +
+ " try {" +
+ " ss.getChannel();" +
+ " } finally {" +
+ " ss.close();" +
+ " }" +
+ " }" +
+ "}");
+ }
+
+ public void testSimple() {
+ doTest("import java.net.*;" +
+ "import java.io.*;" +
+ "class X {" +
+ " void m(SocketInputStream ss) throws IOException {" +
+ " /*'FileChannel' should be opened in front of a 'try' block and closed in the corresponding 'finally' block*/ss.getChannel()/**/;" +
+ " }" +
+ "}");
+ }
+
+ public void testChannelClosed() {
+ doTest("import java.net.*;" +
+ "import java.io.*;" +
+ "class X {" +
+ " void m(SocketInputStream ss) throws IOException {" +
+ " final Closeable channel = ss.getChannel();" +
+ " try {" +
+ " System.out.println();" +
+ " } finally {" +
+ " channel.close();" +
+ " }" +
+ " }" +
+ "}");
+ }
+
+ @Override
+ protected LocalInspectionTool getInspection() {
+ return new ChannelResourceInspection();
+ }
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/JDBCResourceInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/JDBCResourceInspectionTest.java
new file mode 100644
index 0000000..d834557
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/JDBCResourceInspectionTest.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.siyeh.ig.resources;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.siyeh.ig.LightInspectionTestCase;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class JDBCResourceInspectionTest extends LightInspectionTestCase {
+
+ public void testCorrectClose() {
+ doTest("import java.sql.*;" +
+ "class X {" +
+ " public void m(Driver driver) throws SQLException {" +
+ " Connection connection = connection = driver.connect(\"foo\", null);\n" +
+ " try {" +
+ " System.out.println(connection);" +
+ " } finally {" +
+ " connection.close();" +
+ " }" +
+ " }" +
+ "}");
+ }
+
+ public void testARM() {
+ // doesn't work with mock jdk
+ /*doTest("import java.sql.*;" +
+ "class X {" +
+ " void m(Driver driver) throws SQLException {" +
+ " try (Connection connection = driver.connect(\"asdf\", null);" +
+ " PreparedStatement statement = connection.prepareStatement(\"SELECT *\");" +
+ " ResultSet resultSet = statement.executeQuery()) {" +
+ " while (resultSet.next()) {" +
+ " }" +
+ " }" +
+ " }" +
+ "}");*/
+ }
+
+ public void testSimple() {
+ doTest("import java.sql.*;" +
+ "class X {" +
+ " void m(Driver driver) throws SQLException {" +
+ " /*'Connection' should be opened in front of a 'try' block and closed in the corresponding 'finally' block*/driver.connect(\"asdf\", null)/**/;" +
+ " }" +
+ "}");
+ }
+
+ @Override
+ protected LocalInspectionTool getInspection() {
+ return new JDBCResourceInspection();
+ }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/SocketResourceInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/SocketResourceInspectionTest.java
new file mode 100644
index 0000000..4e3c856
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/resources/SocketResourceInspectionTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.siyeh.ig.resources;
+
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.siyeh.ig.LightInspectionTestCase;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class SocketResourceInspectionTest extends LightInspectionTestCase {
+
+ public void testNoCloseNoVar() {
+ doTest("import java.io.*;" +
+ "import java.net.*;" +
+ "class X {" +
+ " public void m() throws IOException, UnknownHostException {" +
+ " /*'Socket' should be opened in front of a 'try' block and closed in the corresponding 'finally' block*/new Socket( InetAddress.getLocalHost(), 1)/**/;" +
+ " }" +
+ "}");
+ }
+
+ public void testNoClose() {
+ doTest("import java.io.*;" +
+ "import java.net.*;" +
+ "class X {" +
+ " public void m() throws IOException, UnknownHostException {" +
+ " final Socket socket = /*'Socket' should be opened in front of a 'try' block and closed in the corresponding 'finally' block*/new Socket(InetAddress.getLocalHost(), 1)/**/;" +
+ " }" +
+ "}");
+ }
+
+ public void testTryNoClose() {
+ doTest("import java.io.*;" +
+ "import java.net.*;" +
+ "class X {" +
+ " public void m() throws IOException, UnknownHostException {" +
+ " try {" +
+ " final Socket socket = /*'Socket' should be opened in front of a 'try' block and closed in the corresponding 'finally' block*/new Socket(InetAddress.getLocalHost(), 1)/**/;" +
+ " } finally {" +
+ " }" +
+ " }" +
+ "}");
+ }
+
+ public void testImmediateClose() {
+ doTest("import java.io.*;" +
+ "import java.net.*;" +
+ "class X {" +
+ " public void m() throws IOException {" +
+ " final Socket socket = new Socket(InetAddress.getLocalHost(), 1);" +
+ " socket.close();" +
+ " }" +
+ "}");
+ }
+
+ public void testCorrectClose() {
+ doTest("import java.io.*;" +
+ "import java.net.*;" +
+ "class X {" +
+ " public void m() throws IOException {" +
+ " Socket socket = new Socket(InetAddress.getLocalHost(), 1);" +
+ " try {" +
+ " } finally {" +
+ " socket.close();" +
+ " }" +
+ " }" +
+ "}");
+ }
+
+ @Override
+ protected LocalInspectionTool getInspection() {
+ return new SocketResourceInspection();
+ }
+}
diff --git a/plugins/ant/src/com/intellij/lang/ant/quickfix/AntUnresolvedRefsFixProvider.java b/plugins/ant/src/com/intellij/lang/ant/quickfix/AntUnresolvedRefsFixProvider.java
index 5df91b5..cf04053 100644
--- a/plugins/ant/src/com/intellij/lang/ant/quickfix/AntUnresolvedRefsFixProvider.java
+++ b/plugins/ant/src/com/intellij/lang/ant/quickfix/AntUnresolvedRefsFixProvider.java
@@ -28,7 +28,7 @@
*/
public class AntUnresolvedRefsFixProvider extends UnresolvedReferenceQuickFixProvider<PsiReference> {
- public void registerFixes(PsiReference ref, QuickFixActionRegistrar registrar) {
+ public void registerFixes(@NotNull PsiReference ref, @NotNull QuickFixActionRegistrar registrar) {
if (ref instanceof TagNameReference || ref instanceof AntDomReference) {
registrar.register(new AntChangeContextFix());
}
diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/actions/AbstractFileProcessor.java b/plugins/copyright/src/com/maddyhome/idea/copyright/actions/AbstractFileProcessor.java
index 4905c5b..21bf3e4 100644
--- a/plugins/copyright/src/com/maddyhome/idea/copyright/actions/AbstractFileProcessor.java
+++ b/plugins/copyright/src/com/maddyhome/idea/copyright/actions/AbstractFileProcessor.java
@@ -121,6 +121,7 @@
final Runnable[] resultRunnable = new Runnable[1];
execute(new Runnable() {
+ @Override
public void run() {
try {
resultRunnable[0] = preprocessFile(file);
@@ -130,6 +131,7 @@
}
}
}, new Runnable() {
+ @Override
public void run() {
if (resultRunnable[0] != null) {
resultRunnable[0].run();
@@ -182,6 +184,7 @@
}
return new Runnable() {
+ @Override
public void run() {
ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
String msg = null;
@@ -219,10 +222,12 @@
private void process(final PsiFile[] files) {
final Runnable[] resultRunnable = new Runnable[1];
execute(new Runnable() {
+ @Override
public void run() {
resultRunnable[0] = prepareFiles(new ArrayList<PsiFile>(Arrays.asList(files)));
}
}, new Runnable() {
+ @Override
public void run() {
if (resultRunnable[0] != null) {
resultRunnable[0].run();
@@ -234,6 +239,7 @@
private void process(final PsiDirectory dir, final boolean subdirs) {
final List<PsiFile> pfiles = new ArrayList<PsiFile>();
ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
+ @Override
public void run() {
findFiles(pfiles, dir, subdirs);
}
@@ -244,6 +250,7 @@
private void process(final Project project) {
final List<PsiFile> pfiles = new ArrayList<PsiFile>();
ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
+ @Override
public void run() {
findFiles(project, pfiles);
}
@@ -254,6 +261,7 @@
private void process(final Module module) {
final List<PsiFile> pfiles = new ArrayList<PsiFile>();
ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
+ @Override
public void run() {
findFiles(module, pfiles);
}
@@ -276,6 +284,7 @@
for (VirtualFile root : roots) {
idx.iterateContentUnderDirectory(root, new ContentIterator() {
+ @Override
public boolean processFile(final VirtualFile dir) {
if (dir.isDirectory()) {
final PsiDirectory psiDir = PsiManager.getInstance(module.getProject()).findDirectory(dir);
@@ -299,10 +308,12 @@
if (!files.isEmpty()) {
final Runnable[] resultRunnable = new Runnable[1];
execute(new Runnable() {
+ @Override
public void run() {
resultRunnable[0] = prepareFiles(files);
}
}, new Runnable() {
+ @Override
public void run() {
if (resultRunnable[0] != null) {
resultRunnable[0].run();
@@ -335,11 +346,13 @@
private void execute(final Runnable readAction, final Runnable writeAction) {
ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
+ @Override
public void run() {
readAction.run();
}
}, title, true, myProject);
new WriteCommandAction(myProject, title) {
+ @Override
protected void run(Result result) throws Throwable {
writeAction.run();
}
diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/ProjectSettingsPanel.java b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/ProjectSettingsPanel.java
index 2391a49..e147f35 100644
--- a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/ProjectSettingsPanel.java
+++ b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/ProjectSettingsPanel.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.
@@ -106,12 +106,14 @@
myScopesLink.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(final HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
- final DataContext dataContext = DataManager.getInstance().getDataContextFromFocus().getResult();
- final OptionsEditor optionsEditor = OptionsEditor.KEY.getData(dataContext);
- if (optionsEditor != null) {
- Configurable configurable = optionsEditor.findConfigurableById(ScopeChooserConfigurable.PROJECT_SCOPES);
- if (configurable != null) {
- optionsEditor.clearSearchAndSelect(configurable);
+ DataContext context = DataManager.getInstance().getDataContextFromFocus().getResult();
+ if (context != null) {
+ OptionsEditor optionsEditor = OptionsEditor.KEY.getData(context);
+ if (optionsEditor != null) {
+ Configurable configurable = optionsEditor.findConfigurableById(ScopeChooserConfigurable.PROJECT_SCOPES);
+ if (configurable != null) {
+ optionsEditor.clearSearchAndSelect(configurable);
+ }
}
}
}
diff --git a/plugins/devkit/src/dom/impl/IdeaPluginConverter.java b/plugins/devkit/src/dom/impl/IdeaPluginConverter.java
index 94c6d83..60f72ac 100644
--- a/plugins/devkit/src/dom/impl/IdeaPluginConverter.java
+++ b/plugins/devkit/src/dom/impl/IdeaPluginConverter.java
@@ -22,6 +22,7 @@
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.GlobalSearchScopesCore;
import com.intellij.util.Function;
+import com.intellij.util.PlatformUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xml.ConvertContext;
import com.intellij.util.xml.DomFileElement;
@@ -107,7 +108,8 @@
public static Collection<IdeaPlugin> getAllPlugins(final Project project) {
if (DumbService.isDumb(project)) return Collections.emptyList();
- GlobalSearchScope scope = GlobalSearchScopesCore.projectProductionScope(project);
+ GlobalSearchScope scope = PlatformUtils.isIdeaProject(project) ?
+ GlobalSearchScopesCore.projectProductionScope(project) : GlobalSearchScope.allScope(project);
List<DomFileElement<IdeaPlugin>> files = DomService.getInstance().getFileElements(IdeaPlugin.class, project, scope);
return ContainerUtil.map(files, new Function<DomFileElement<IdeaPlugin>, IdeaPlugin>() {
public IdeaPlugin fun(DomFileElement<IdeaPlugin> ideaPluginDomFileElement) {
diff --git a/plugins/github/github.iml b/plugins/github/github.iml
index ea922cf..50d0f79 100644
--- a/plugins/github/github.iml
+++ b/plugins/github/github.iml
@@ -20,6 +20,8 @@
<orderEntry type="library" name="gson" level="project" />
<orderEntry type="module" module-name="dvcs" />
<orderEntry type="module" module-name="testFramework" scope="TEST" />
+ <orderEntry type="module" module-name="xml-openapi" />
+ <orderEntry type="module" module-name="xml" />
</component>
</module>
diff --git a/plugins/github/src/META-INF/plugin.xml b/plugins/github/src/META-INF/plugin.xml
index 86240aa..4af448e 100644
--- a/plugins/github/src/META-INF/plugin.xml
+++ b/plugins/github/src/META-INF/plugin.xml
@@ -19,6 +19,7 @@
<applicationService serviceInterface="org.jetbrains.plugins.github.util.GithubSslSupport"
serviceImplementation="org.jetbrains.plugins.github.util.GithubSslSupport"/>
+ <webBrowserUrlProvider implementation="org.jetbrains.plugins.github.extensions.GithubWebBrowserUrlProvider"/>
</extensions>
<extensions defaultExtensionNs="Git4Idea">
diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java
index 4399bae..a633c5f 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java
@@ -49,7 +49,7 @@
public static final String CANNOT_OPEN_IN_BROWSER = "Cannot open in browser";
protected GithubOpenInBrowserAction() {
- super("Open in browser", "Open corresponding GitHub link in browser", GithubIcons.Github_icon);
+ super("Open on GitHub", "Open corresponding link in browser", GithubIcons.Github_icon);
}
@Override
@@ -92,51 +92,65 @@
public void actionPerformed(final AnActionEvent e) {
final Project project = e.getData(PlatformDataKeys.PROJECT);
final VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE);
+ final Editor editor = e.getData(PlatformDataKeys.EDITOR);
if (virtualFile == null || project == null || project.isDisposed()) {
return;
}
+ String urlToOpen = getGithubUrl(project, virtualFile, editor, false);
+ if (urlToOpen != null) {
+ BrowserUtil.launchBrowser(urlToOpen);
+ }
+ }
+
+ @Nullable
+ public static String getGithubUrl(@NotNull Project project, @NotNull VirtualFile virtualFile, @Nullable Editor editor, boolean quiet) {
+
GitRepositoryManager manager = GitUtil.getRepositoryManager(project);
final GitRepository repository = manager.getRepositoryForFile(virtualFile);
if (repository == null) {
- StringBuilder details = new StringBuilder("file: " + virtualFile.getPresentableUrl() + "; Git repositories: ");
- for (GitRepository repo : manager.getRepositories()) {
- details.append(repo.getPresentableUrl()).append("; ");
+ if (!quiet) {
+ StringBuilder details = new StringBuilder("file: " + virtualFile.getPresentableUrl() + "; Git repositories: ");
+ for (GitRepository repo : manager.getRepositories()) {
+ details.append(repo.getPresentableUrl()).append("; ");
+ }
+ showError(project, "Can't find git repository", details.toString(), quiet);
}
- GithubNotifications.showError(project, CANNOT_OPEN_IN_BROWSER, "Can't find git repository", details.toString());
- return;
+ return null;
}
final String githubRemoteUrl = GithubUtil.findGithubRemoteUrl(repository);
if (githubRemoteUrl == null) {
- GithubNotifications.showError(project, CANNOT_OPEN_IN_BROWSER, "Can't find github remote");
- return;
+ showError(project, "Can't find github remote", null, quiet);
+ return null;
}
final String rootPath = repository.getRoot().getPath();
final String path = virtualFile.getPath();
if (!path.startsWith(rootPath)) {
- GithubNotifications
- .showError(project, CANNOT_OPEN_IN_BROWSER, "File is not under repository root", "Root: " + rootPath + ", file: " + path);
- return;
+ showError(project, "File is not under repository root", "Root: " + rootPath + ", file: " + path, quiet);
+ return null;
}
- String branch = getBranchNameOnRemote(project, repository);
+ String branch = getBranchNameOnRemote(project, repository, quiet);
if (branch == null) {
- return;
+ return null;
}
String relativePath = path.substring(rootPath.length());
- String urlToOpen = makeUrlToOpen(e, relativePath, branch, githubRemoteUrl);
+ String urlToOpen = makeUrlToOpen(editor, relativePath, branch, githubRemoteUrl);
if (urlToOpen == null) {
- GithubNotifications.showError(project, CANNOT_OPEN_IN_BROWSER, "Can't create properly url", githubRemoteUrl);
- return;
+ showError(project, "Can't create properly url", githubRemoteUrl, quiet);
+ return null;
}
- BrowserUtil.launchBrowser(urlToOpen);
+
+ return urlToOpen;
}
@Nullable
- private static String makeUrlToOpen(@NotNull AnActionEvent e, @NotNull String relativePath, @NotNull String branch,
+ private static String makeUrlToOpen(@Nullable Editor editor,
+ @NotNull String relativePath,
+ @NotNull String branch,
@NotNull String githubRemoteUrl) {
final StringBuilder builder = new StringBuilder();
final String githubRepoUrl = GithubUrlUtil.makeGithubRepoUrlFromRemoteUrl(githubRemoteUrl);
@@ -145,7 +159,6 @@
}
builder.append(githubRepoUrl).append("/blob/").append(branch).append(relativePath);
- final Editor editor = e.getData(PlatformDataKeys.EDITOR);
if (editor != null && editor.getDocument().getLineCount() >= 1) {
// lines are counted internally from 0, but from 1 on github
SelectionModel selectionModel = editor.getSelectionModel();
@@ -162,23 +175,31 @@
}
@Nullable
- public static String getBranchNameOnRemote(@NotNull Project project, @NotNull GitRepository repository) {
+ public static String getBranchNameOnRemote(@NotNull Project project, @NotNull GitRepository repository, boolean quiet) {
GitLocalBranch currentBranch = repository.getCurrentBranch();
if (currentBranch == null) {
- GithubNotifications.showError(project, CANNOT_OPEN_IN_BROWSER,
- "Can't open the file on GitHub when repository is on detached HEAD. Please checkout a branch.");
+ showError(project, "Can't open the file on GitHub when repository is on detached HEAD. Please checkout a branch.", null, quiet);
return null;
}
GitRemoteBranch tracked = currentBranch.findTrackedBranch(repository);
if (tracked == null) {
- GithubNotifications
- .showError(project, CANNOT_OPEN_IN_BROWSER, "Can't open the file on GitHub when current branch doesn't have a tracked branch.",
- "Current branch: " + currentBranch + ", tracked info: " + repository.getBranchTrackInfos());
+ showError(project, "Can't open the file on GitHub when current branch doesn't have a tracked branch.",
+ "Current branch: " + currentBranch + ", tracked info: " + repository.getBranchTrackInfos(), quiet);
return null;
}
return tracked.getNameForRemoteOperations();
}
+ private static void showError(@NotNull Project project, @NotNull String message, @Nullable String details, boolean quiet) {
+ if (!quiet) {
+ if (details == null) {
+ GithubNotifications.showError(project, CANNOT_OPEN_IN_BROWSER, message);
+ }
+ else {
+ GithubNotifications.showError(project, CANNOT_OPEN_IN_BROWSER, message, details);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserAction.java
index 1dc7aad..607d9d9 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserAction.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/GithubShowCommitInBrowserAction.java
@@ -32,7 +32,7 @@
abstract class GithubShowCommitInBrowserAction extends DumbAwareAction {
public GithubShowCommitInBrowserAction() {
- super("Open in Browser", "Open the selected commit in browser", GithubIcons.Github_icon);
+ super("Open on GitHub", "Open the selected commit in browser", GithubIcons.Github_icon);
}
protected static void openInBrowser(Project project, GitRepository repository, String revisionHash) {
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
index ba7a8cd..2f634d0 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
@@ -135,7 +135,7 @@
@Nullable final String requestBody,
@NotNull final Collection<Header> headers,
@NotNull final HttpVerb verb) throws IOException {
- HttpClient client = getHttpClient(auth.getBasicAuth());
+ HttpClient client = getHttpClient(auth.getBasicAuth(), auth.isUseProxy());
return GithubSslSupport.getInstance()
.executeSelfSignedCertificateAwareRequest(client, uri, new ThrowableConvertor<String, HttpMethod, IOException>() {
@Override
@@ -173,7 +173,7 @@
}
@NotNull
- private static HttpClient getHttpClient(@Nullable GithubAuthData.BasicAuth basicAuth) {
+ private static HttpClient getHttpClient(@Nullable GithubAuthData.BasicAuth basicAuth, boolean useProxy) {
final HttpClient client = new HttpClient();
HttpConnectionManagerParams params = client.getHttpConnectionManager().getParams();
params.setConnectionTimeout(CONNECTION_TIMEOUT); //set connection timeout (how long it takes to connect to remote host)
@@ -182,7 +182,7 @@
client.getParams().setContentCharset("UTF-8");
// Configure proxySettings if it is required
final HttpConfigurable proxySettings = HttpConfigurable.getInstance();
- if (proxySettings.USE_HTTP_PROXY && !StringUtil.isEmptyOrSpaces(proxySettings.PROXY_HOST)) {
+ if (useProxy && proxySettings.USE_HTTP_PROXY && !StringUtil.isEmptyOrSpaces(proxySettings.PROXY_HOST)) {
client.getHostConfiguration().setProxy(proxySettings.PROXY_HOST, proxySettings.PROXY_PORT);
if (proxySettings.PROXY_AUTHENTICATION) {
client.getState().setProxyCredentials(AuthScope.ANY, new UsernamePasswordCredentials(proxySettings.PROXY_LOGIN,
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubAuthorization.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubAuthorization.java
index d970771..ad34cbd 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubAuthorization.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubAuthorization.java
@@ -23,8 +23,8 @@
* @author Aleksey Pivovarov
*/
public class GithubAuthorization {
- @NotNull private String myToken;
- @NotNull private List<String> myScopes;
+ @NotNull private final String myToken;
+ @NotNull private final List<String> myScopes;
public GithubAuthorization(@NotNull String token, @NotNull List<String> scopes) {
myToken = token;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubAuthorizationRequest.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubAuthorizationRequest.java
index 1639862..705cdbd 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubAuthorizationRequest.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubAuthorizationRequest.java
@@ -25,10 +25,10 @@
*/
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
class GithubAuthorizationRequest {
- @NotNull List<String> scopes;
+ @NotNull private final List<String> scopes;
- @Nullable String note;
- @Nullable String noteUrl;
+ @Nullable private final String note;
+ @Nullable private final String noteUrl;
public GithubAuthorizationRequest(@NotNull List<String> scopes, @Nullable String note, @Nullable String noteUrl) {
this.scopes = scopes;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubBranch.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubBranch.java
index 792303f..cffb740 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubBranch.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubBranch.java
@@ -21,7 +21,7 @@
* @author Aleksey Pivovarov
*/
public class GithubBranch {
- @NotNull private String name;
+ @NotNull private final String name;
public GithubBranch(@NotNull String name) {
this.name = name;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommit.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommit.java
index 30b2c1c..5504406 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommit.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommit.java
@@ -26,18 +26,18 @@
*/
@SuppressWarnings("UnusedDeclaration")
public class GithubCommit extends GithubCommitSha {
- @Nullable private GithubUser myAuthor;
- @Nullable private GithubUser myCommitter;
+ @Nullable private final GithubUser myAuthor;
+ @Nullable private final GithubUser myCommitter;
- @NotNull private List<GithubCommitSha> myParents;
+ @NotNull private final List<GithubCommitSha> myParents;
- @NotNull private GitCommit myCommit;
+ @NotNull private final GitCommit myCommit;
public static class GitCommit {
- @NotNull private String myMessage;
+ @NotNull private final String myMessage;
- @NotNull private GitUser myAuthor;
- @NotNull private GitUser myCommitter;
+ @NotNull private final GitUser myAuthor;
+ @NotNull private final GitUser myCommitter;
public GitCommit(@NotNull String message, @NotNull GitUser author, @NotNull GitUser committer) {
myMessage = message;
@@ -62,9 +62,9 @@
}
public static class GitUser {
- @NotNull private String myName;
- @NotNull private String myEmail;
- @NotNull private Date myDate;
+ @NotNull private final String myName;
+ @NotNull private final String myEmail;
+ @NotNull private final Date myDate;
public GitUser(@NotNull String name, @NotNull String email, @NotNull Date date) {
myName = name;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitDetailed.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitDetailed.java
index 1e56225..92cd674 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitDetailed.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitDetailed.java
@@ -25,13 +25,13 @@
*/
@SuppressWarnings("UnusedDeclaration")
public class GithubCommitDetailed extends GithubCommit {
- @NotNull private CommitStats myStats;
- @NotNull private List<GithubFile> myFiles;
+ @NotNull private final CommitStats myStats;
+ @NotNull private final List<GithubFile> myFiles;
public static class CommitStats {
- private int myAdditions;
- private int myDeletions;
- private int myTotal;
+ private final int myAdditions;
+ private final int myDeletions;
+ private final int myTotal;
public CommitStats(int additions, int deletions, int total) {
myAdditions = additions;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitSha.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitSha.java
index 83b89df..f79e6bc 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitSha.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitSha.java
@@ -22,8 +22,8 @@
*/
@SuppressWarnings("UnusedDeclaration")
public class GithubCommitSha {
- @NotNull private String myUrl;
- @NotNull private String mySha;
+ @NotNull private final String myUrl;
+ @NotNull private final String mySha;
public GithubCommitSha(@NotNull String url, @NotNull String sha) {
myUrl = url;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubFile.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubFile.java
index ea91051..73efe26 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubFile.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubFile.java
@@ -22,15 +22,15 @@
*/
@SuppressWarnings("UnusedDeclaration")
public class GithubFile {
- @NotNull private String myFilename;
+ @NotNull private final String myFilename;
- private int myAdditions;
- private int myDeletions;
- private int myChanges;
- @NotNull private String myStatus;
+ private final int myAdditions;
+ private final int myDeletions;
+ private final int myChanges;
+ @NotNull private final String myStatus;
- @NotNull private String myRawUrl;
- @NotNull private String myPatch;
+ @NotNull private final String myRawUrl;
+ @NotNull private final String myPatch;
public GithubFile(@NotNull String filename, int additions,
int deletions,
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubFullPath.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubFullPath.java
index fb7d6e6..7488c17 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubFullPath.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubFullPath.java
@@ -21,8 +21,8 @@
* @author Aleksey Pivovarov
*/
public class GithubFullPath {
- @NotNull final private String myUserName;
- @NotNull final private String myRepositoryName;
+ @NotNull private final String myUserName;
+ @NotNull private final String myRepositoryName;
public GithubFullPath(@NotNull String userName, @NotNull String repositoryName) {
myUserName = userName;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubGist.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubGist.java
index 5ff4d35..4f2deb9 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubGist.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubGist.java
@@ -26,22 +26,22 @@
* @author Aleksey Pivovarov
*/
public class GithubGist {
- @NotNull private String myId;
- @NotNull private String myDescription;
+ @NotNull private final String myId;
+ @NotNull private final String myDescription;
- private boolean myIsPublic;
+ private final boolean myIsPublic;
- @NotNull private String myHtmlUrl;
+ @NotNull private final String myHtmlUrl;
- @NotNull private List<GistFile> myFiles;
+ @NotNull private final List<GistFile> myFiles;
- @Nullable private GithubUser myUser;
+ @Nullable private final GithubUser myUser;
public static class GistFile {
- @NotNull private String myFilename;
- @NotNull private String myContent;
+ @NotNull private final String myFilename;
+ @NotNull private final String myContent;
- @NotNull private String myRawUrl;
+ @NotNull private final String myRawUrl;
public GistFile(@NotNull String filename, @NotNull String content, @NotNull String rawUrl) {
myFilename = filename;
@@ -118,8 +118,8 @@
}
public static class FileContent {
- @NotNull private String myFileName;
- @NotNull private String myContent;
+ @NotNull private final String myFileName;
+ @NotNull private final String myContent;
public FileContent(@NotNull String fileName, @NotNull String content) {
myFileName = fileName;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubGistRequest.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubGistRequest.java
index 23bd291..fe0f49b 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubGistRequest.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubGistRequest.java
@@ -25,16 +25,16 @@
/**
* @author Aleksey Pivovarov
*/
-@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
+@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration", "MismatchedQueryAndUpdateOfCollection"})
class GithubGistRequest {
- @NotNull private String description;
- @NotNull private Map<String, GistFile> files;
+ @NotNull private final String description;
+ @NotNull private final Map<String, GistFile> files;
@SerializedName("public")
- private boolean isPublic;
+ private final boolean isPublic;
public static class GistFile {
- @NotNull private String content;
+ @NotNull private final String content;
public GistFile(@NotNull String content) {
this.content = content;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssue.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssue.java
index 771dc5c..f521548 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssue.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssue.java
@@ -25,18 +25,18 @@
* @author Aleksey Pivovarov
*/
public class GithubIssue {
- @NotNull private String myHtmlUrl;
- private long myNumber;
- @NotNull private String myState;
- @NotNull private String myTitle;
- @NotNull private String myBody;
+ @NotNull private final String myHtmlUrl;
+ private final long myNumber;
+ @NotNull private final String myState;
+ @NotNull private final String myTitle;
+ @NotNull private final String myBody;
- @NotNull private GithubUser myUser;
- @Nullable private GithubUser myAssignee;
+ @NotNull private final GithubUser myUser;
+ @Nullable private final GithubUser myAssignee;
- @Nullable Date myClosedAt;
- @NotNull Date myCreatedAt;
- @NotNull Date myUpdatedAt;
+ @Nullable private final Date myClosedAt;
+ @NotNull private final Date myCreatedAt;
+ @NotNull private final Date myUpdatedAt;
public GithubIssue(@NotNull String htmlUrl,
long number,
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssueComment.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssueComment.java
index 5faf9a4..da17175 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssueComment.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssueComment.java
@@ -23,15 +23,15 @@
* @author Aleksey Pivovarov
*/
public class GithubIssueComment {
- private long myId;
+ private final long myId;
- @NotNull private String myHtmlUrl;
- @NotNull private String myBodyHtml;
+ @NotNull private final String myHtmlUrl;
+ @NotNull private final String myBodyHtml;
- @NotNull private Date myCreatedAt;
- @NotNull private Date myUpdatedAt;
+ @NotNull private final Date myCreatedAt;
+ @NotNull private final Date myUpdatedAt;
- @NotNull private GithubUser myUser;
+ @NotNull private final GithubUser myUser;
public GithubIssueComment(long id,
@NotNull String htmlUrl,
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssuesSearchResult.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssuesSearchResult.java
index b129b2c..d79be87 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssuesSearchResult.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssuesSearchResult.java
@@ -24,7 +24,7 @@
*/
@SuppressWarnings("UnusedDeclaration")
public class GithubIssuesSearchResult {
- @NotNull private List<GithubIssue> issues;
+ @NotNull private final List<GithubIssue> issues;
public GithubIssuesSearchResult(@NotNull List<GithubIssue> issues) {
this.issues = issues;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssuesSearchResultRaw.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssuesSearchResultRaw.java
index 7656832c..ebe816c 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssuesSearchResultRaw.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubIssuesSearchResultRaw.java
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.github.api;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
@@ -23,9 +24,9 @@
/**
* @author Aleksey Pivovarov
*/
-@SuppressWarnings("UnusedDeclaration")
+@SuppressWarnings({"UnusedDeclaration", "ConstantConditions"})
class GithubIssuesSearchResultRaw implements DataConstructor {
- List<GithubIssueRaw> items;
+ @Nullable public List<GithubIssueRaw> items;
@NotNull
GithubIssuesSearchResult createIssueSearchResult() {
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubOrg.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubOrg.java
index 7a691fb..029c8aa5 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubOrg.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubOrg.java
@@ -21,7 +21,7 @@
* @author Aleksey Pivovarov
*/
public class GithubOrg {
- @NotNull String myLogin;
+ @NotNull private final String myLogin;
public GithubOrg(@NotNull String login) {
myLogin = login;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubPullRequest.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubPullRequest.java
index 1a8facb..66794de 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubPullRequest.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubPullRequest.java
@@ -26,33 +26,33 @@
*/
@SuppressWarnings("UnusedDeclaration")
public class GithubPullRequest {
- private long myNumber;
- @NotNull private String myState;
- @NotNull private String myTitle;
- @NotNull private String myBodyHtml;
+ private final long myNumber;
+ @NotNull private final String myState;
+ @NotNull private final String myTitle;
+ @NotNull private final String myBodyHtml;
- @NotNull private String myHtmlUrl;
- @NotNull private String myDiffUrl;
- @NotNull private String myPatchUrl;
- @NotNull private String myIssueUrl;
+ @NotNull private final String myHtmlUrl;
+ @NotNull private final String myDiffUrl;
+ @NotNull private final String myPatchUrl;
+ @NotNull private final String myIssueUrl;
- @NotNull private Date myCreatedAt;
- @NotNull private Date myUpdatedAt;
- @Nullable private Date myClosedAt;
- @Nullable private Date myMergedAt;
+ @NotNull private final Date myCreatedAt;
+ @NotNull private final Date myUpdatedAt;
+ @Nullable private final Date myClosedAt;
+ @Nullable private final Date myMergedAt;
- @NotNull private GithubUser myUser;
+ @NotNull private final GithubUser myUser;
- @NotNull private Link myHead;
- @NotNull private Link myBase;
+ @NotNull private final Link myHead;
+ @NotNull private final Link myBase;
public static class Link {
- @NotNull private String myLabel;
- @NotNull private String myRef;
- @NotNull private String mySha;
+ @NotNull private final String myLabel;
+ @NotNull private final String myRef;
+ @NotNull private final String mySha;
- @NotNull private GithubRepo myRepo;
- @NotNull private GithubUser myUser;
+ @NotNull private final GithubRepo myRepo;
+ @NotNull private final GithubUser myUser;
public Link(@NotNull String label, @NotNull String ref, @NotNull String sha, @NotNull GithubRepo repo, @NotNull GithubUser user) {
myLabel = label;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubPullRequestRequest.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubPullRequestRequest.java
index 4465f08..845e743 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubPullRequestRequest.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubPullRequestRequest.java
@@ -20,11 +20,12 @@
/**
* @author Aleksey Pivovarov
*/
+@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
class GithubPullRequestRequest {
- @NotNull String title;
- @NotNull String body;
- @NotNull String head; // branch with changes
- @NotNull String base; // branch requested to
+ @NotNull private final String title;
+ @NotNull private final String body;
+ @NotNull private final String head; // branch with changes
+ @NotNull private final String base; // branch requested to
public GithubPullRequestRequest(@NotNull String title, @NotNull String description, @NotNull String head, @NotNull String base) {
this.title = title;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepo.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepo.java
index 047562d..867079b 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepo.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepo.java
@@ -23,18 +23,18 @@
* @author Aleksey Pivovarov
*/
public class GithubRepo {
- @NotNull private String myName;
- @NotNull private String myDescription;
+ @NotNull private final String myName;
+ @NotNull private final String myDescription;
- private boolean myIsPrivate;
- private boolean myIsFork;
+ private final boolean myIsPrivate;
+ private final boolean myIsFork;
- @NotNull private String myHtmlUrl;
- @NotNull private String myCloneUrl;
+ @NotNull private final String myHtmlUrl;
+ @NotNull private final String myCloneUrl;
- @Nullable private String myDefaultBranch;
+ @Nullable private final String myDefaultBranch;
- @NotNull private GithubUser myOwner;
+ @NotNull private final GithubUser myOwner;
public GithubRepo(@NotNull String name,
@Nullable String description,
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepoDetailed.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepoDetailed.java
index a9e1a69..16f73ca 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepoDetailed.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepoDetailed.java
@@ -22,8 +22,8 @@
* @author Aleksey Pivovarov
*/
public class GithubRepoDetailed extends GithubRepo {
- @Nullable private GithubRepo myParent;
- @Nullable private GithubRepo mySource;
+ @Nullable private final GithubRepo myParent;
+ @Nullable private final GithubRepo mySource;
public GithubRepoDetailed(@NotNull String name,
@Nullable String description,
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepoOrg.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepoOrg.java
index fda0462..5a317b2e 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepoOrg.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepoOrg.java
@@ -21,13 +21,14 @@
/**
* @author Aleksey Pivovarov
*/
+@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
public class GithubRepoOrg extends GithubRepo {
- @NotNull Permissions myPermissions;
+ @NotNull private final Permissions myPermissions;
public static class Permissions {
- private boolean myAdmin;
- private boolean myPull;
- private boolean myPush;
+ private final boolean myAdmin;
+ private final boolean myPull;
+ private final boolean myPush;
public Permissions(boolean admin, boolean pull, boolean push) {
myAdmin = admin;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepoRequest.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepoRequest.java
index fbd0377..9eb5cc45 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepoRequest.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubRepoRequest.java
@@ -23,10 +23,10 @@
*/
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
class GithubRepoRequest {
- @NotNull String name;
- @NotNull String description;
+ @NotNull private final String name;
+ @NotNull private final String description;
- @SerializedName("public") boolean isPublic;
+ @SerializedName("public") private final boolean isPublic;
GithubRepoRequest(@NotNull String name, @NotNull String description, boolean aPublic) {
this.name = name;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubUser.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubUser.java
index 07624a1..29ef1ac 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubUser.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubUser.java
@@ -22,11 +22,11 @@
* @author Aleksey Pivovarov
*/
public class GithubUser {
- @NotNull private String myLogin;
+ @NotNull private final String myLogin;
- @NotNull private String myHtmlUrl;
+ @NotNull private final String myHtmlUrl;
- @Nullable private String myGravatarId;
+ @Nullable private final String myGravatarId;
public GithubUser(@NotNull String login, @NotNull String htmlUrl, @Nullable String gravatarId) {
myLogin = login;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubUserDetailed.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubUserDetailed.java
index 74ab021..c56bb44 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubUserDetailed.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubUserDetailed.java
@@ -22,17 +22,17 @@
* @author Aleksey Pivovarov
*/
public class GithubUserDetailed extends GithubUser {
- @Nullable private String myName;
- @Nullable private String myEmail;
+ @Nullable private final String myName;
+ @Nullable private final String myEmail;
- private int myOwnedPrivateRepos;
+ private final int myOwnedPrivateRepos;
- @NotNull private String myType;
- @NotNull private UserPlan myPlan;
+ @NotNull private final String myType;
+ @NotNull private final UserPlan myPlan;
public static class UserPlan {
- @NotNull private String myName;
- private long myPrivateRepos;
+ @NotNull private final String myName;
+ private final long myPrivateRepos;
public UserPlan(@NotNull String name, long privateRepos) {
myName = name;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubWebBrowserUrlProvider.java b/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubWebBrowserUrlProvider.java
new file mode 100644
index 0000000..bd3b42e
--- /dev/null
+++ b/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubWebBrowserUrlProvider.java
@@ -0,0 +1,47 @@
+/*
+ * 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 org.jetbrains.plugins.github.extensions;
+
+import com.intellij.ide.browsers.Url;
+import com.intellij.ide.browsers.UrlImpl;
+import com.intellij.ide.browsers.WebBrowserUrlProvider;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.github.GithubOpenInBrowserAction;
+
+/**
+ * @author Aleksey Pivovarov
+ */
+public class GithubWebBrowserUrlProvider extends WebBrowserUrlProvider {
+ @Nullable
+ @Override
+ public Url getUrl(@NotNull PsiElement element, @NotNull PsiFile psiFile, @NotNull VirtualFile virtualFile) throws BrowserException {
+ String url = GithubOpenInBrowserAction.getGithubUrl(element.getProject(), virtualFile, null, true);
+ if (url == null) {
+ return null;
+ }
+ return new UrlImpl(url, "https", null, null, null);
+ }
+
+ @Nullable
+ @Override
+ public String getOpenInBrowserActionText(@NotNull PsiFile file) {
+ return "Open on GitHub";
+ }
+}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java
index 4f46266..f4e4554 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java
@@ -18,6 +18,9 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.api.GithubApiUtil;
+import org.jetbrains.plugins.github.exceptions.GithubAuthenticationException;
+import org.jetbrains.plugins.github.exceptions.GithubJsonException;
+import org.jetbrains.plugins.github.exceptions.GithubStatusCodeException;
import org.jetbrains.plugins.github.util.GithubAuthData;
import org.jetbrains.plugins.github.util.GithubUtil;
import org.jetbrains.plugins.github.api.GithubIssue;
@@ -81,7 +84,18 @@
@Override
public Task[] getIssues(@Nullable String query, int max, long since) throws Exception {
- return getIssues(query);
+ try {
+ return getIssues(query);
+ }
+ catch (GithubAuthenticationException e) {
+ throw new Exception(e.getMessage(), e);
+ }
+ catch (GithubStatusCodeException e) {
+ throw new Exception(e.getMessage(), e);
+ }
+ catch (GithubJsonException e) {
+ throw new Exception("Bad response format", e);
+ }
}
@NotNull
@@ -269,7 +283,7 @@
}
private GithubAuthData getAuthData() {
- return GithubAuthData.createTokenAuth(getUrl(), getToken());
+ return GithubAuthData.createTokenAuth(getUrl(), getToken(), isUseProxy());
}
@Override
@@ -287,6 +301,6 @@
@Override
protected int getFeatures() {
- return BASIC_HTTP_AUTHORIZATION;
+ return super.getFeatures() | BASIC_HTTP_AUTHORIZATION;
}
}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java
index fe63449..2a83c85 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java
@@ -1,16 +1,16 @@
package org.jetbrains.plugins.github.tasks;
import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.tasks.config.BaseRepositoryEditor;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.components.JBLabel;
+import com.intellij.ui.components.JBTextField;
import com.intellij.util.Consumer;
import com.intellij.util.ThrowableConvertor;
import com.intellij.util.ui.FormBuilder;
+import com.intellij.util.ui.GridBag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.util.GithubAuthData;
@@ -31,25 +31,29 @@
* @author Dennis.Ushakov
*/
public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepository> {
- private JTextField myToken;
- private JTextField myRepoName;
- private JTextField myRepoAuthor;
+ private MyTextField myHost;
+ private MyTextField myRepoAuthor;
+ private MyTextField myRepoName;
+ private MyTextField myToken;
private JButton myTokenButton;
- private JBLabel myRepoAuthorLabel;
- private JBLabel myRepoLabel;
+ private JBLabel myHostLabel;
+ private JBLabel myRepositoryLabel;
private JBLabel myTokenLabel;
public GithubRepositoryEditor(final Project project, final GithubRepository repository, Consumer<GithubRepository> changeListener) {
super(project, repository, changeListener);
- myUserNameText.setVisible(false);
+ myUrlLabel.setVisible(false);
+ myURLText.setVisible(false);
myUsernameLabel.setVisible(false);
- myPasswordText.setVisible(false);
+ myUserNameText.setVisible(false);
myPasswordLabel.setVisible(false);
+ myPasswordText.setVisible(false);
myUseHttpAuthenticationCheckBox.setVisible(false);
- myToken.setText(repository.getToken());
+ myHost.setText(repository.getUrl());
myRepoAuthor.setText(repository.getRepoAuthor());
myRepoName.setText(repository.getRepoName());
+ myToken.setText(repository.getToken());
DocumentListener buttonUpdater = new DocumentAdapter() {
@Override
@@ -58,29 +62,36 @@
}
};
+ myHost.getDocument().addDocumentListener(buttonUpdater);
myRepoAuthor.getDocument().addDocumentListener(buttonUpdater);
myRepoName.getDocument().addDocumentListener(buttonUpdater);
myURLText.getDocument().addDocumentListener(buttonUpdater);
-
- setAnchor(myRepoAuthorLabel);
}
@Nullable
@Override
protected JComponent createCustomPanel() {
- myUrlLabel.setText("Host:");
+ myHostLabel = new JBLabel("Host:", SwingConstants.RIGHT);
+ myHost = new MyTextField("Github host");
- myRepoAuthorLabel = new JBLabel("Repository Owner:", SwingConstants.RIGHT);
- myRepoAuthor = new JTextField();
- installListener(myRepoAuthor);
+ JPanel myHostPanel = new JPanel(new BorderLayout(5, 0));
+ myHostPanel.add(myHost, BorderLayout.CENTER);
+ myHostPanel.add(myShareUrlCheckBox, BorderLayout.EAST);
- myRepoLabel = new JBLabel("Repository:", SwingConstants.RIGHT);
- myRepoName = new JTextField();
- installListener(myRepoName);
+ myRepositoryLabel = new JBLabel("Repository:", SwingConstants.RIGHT);
+ myRepoAuthor = new MyTextField("Repository Owner");
+ myRepoName = new MyTextField("Repository Name");
+ myRepoAuthor.setPreferredSize("SomelongNickname");
+ myRepoName.setPreferredSize("SomelongReponame-with-suffixes");
+
+ JPanel myRepoPanel = new JPanel(new GridBagLayout());
+ GridBag bag = new GridBag().setDefaultWeightX(1).setDefaultFill(GridBagConstraints.HORIZONTAL);
+ myRepoPanel.add(myRepoAuthor, bag.nextLine().next());
+ myRepoPanel.add(new JLabel("/"), bag.next().fillCellNone().insets(0, 5, 0, 5).weightx(0));
+ myRepoPanel.add(myRepoName, bag.next());
myTokenLabel = new JBLabel("API Token:", SwingConstants.RIGHT);
- myToken = new JTextField();
- installListener(myToken);
+ myToken = new MyTextField("OAuth2 token");
myTokenButton = new JButton("Create API token");
myTokenButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
@@ -94,8 +105,13 @@
myTokenPanel.add(myToken, BorderLayout.CENTER);
myTokenPanel.add(myTokenButton, BorderLayout.EAST);
- return FormBuilder.createFormBuilder().setAlignLabelOnRight(true).addLabeledComponent(myRepoAuthorLabel, myRepoAuthor)
- .addLabeledComponent(myRepoLabel, myRepoName).addLabeledComponent(myTokenLabel, myTokenPanel).getPanel();
+ installListener(myHost);
+ installListener(myRepoAuthor);
+ installListener(myRepoName);
+ installListener(myToken);
+
+ return FormBuilder.createFormBuilder().setAlignLabelOnRight(true).addLabeledComponent(myHostLabel, myHostPanel)
+ .addLabeledComponent(myRepositoryLabel, myRepoPanel).addLabeledComponent(myTokenLabel, myTokenPanel).getPanel();
}
@Override
@@ -133,8 +149,8 @@
@Override
public void setAnchor(@Nullable final JComponent anchor) {
super.setAnchor(anchor);
- myRepoAuthorLabel.setAnchor(anchor);
- myRepoLabel.setAnchor(anchor);
+ myHostLabel.setAnchor(anchor);
+ myRepositoryLabel.setAnchor(anchor);
myTokenLabel.setAnchor(anchor);
}
@@ -149,9 +165,14 @@
}
}
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return myHost;
+ }
+
@NotNull
private String getHost() {
- return myURLText.getText().trim();
+ return myHost.getText().trim();
}
@NotNull
@@ -168,4 +189,25 @@
private String getToken() {
return myToken.getText().trim();
}
+
+ public static class MyTextField extends JBTextField {
+ private int myWidth = -1;
+
+ public MyTextField(@NotNull String hintCaption) {
+ getEmptyText().setText(hintCaption);
+ }
+
+ public void setPreferredSize(@NotNull String sampleSizeString) {
+ myWidth = getFontMetrics(getFont()).stringWidth(sampleSizeString);
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ Dimension size = super.getPreferredSize();
+ if (myWidth != -1) {
+ size.width = myWidth;
+ }
+ return size;
+ }
+ }
}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form
index c0d2af8..b540bd9 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form
+++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.github.ui.GithubSettingsPanel">
- <grid id="27dc6" binding="myPane" layout-manager="GridLayoutManager" row-count="5" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="27dc6" binding="myPane" layout-manager="GridLayoutManager" row-count="4" column-count="5" 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="563" height="400"/>
@@ -8,25 +8,9 @@
<properties/>
<border type="none"/>
<children>
- <component id="e76ec" class="javax.swing.JTextField" binding="myLoginTextField">
- <constraints>
- <grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
- <preferred-size width="150" height="-1"/>
- </grid>
- </constraints>
- <properties/>
- </component>
- <component id="c0234" class="javax.swing.JLabel" binding="myLoginLabel">
- <constraints>
- <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text value="Login:"/>
- </properties>
- </component>
<component id="28ddd" class="javax.swing.JTextPane" binding="mySignupTextField">
<constraints>
- <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="2" anchor="0" fill="1" indent="0" use-parent-layout="false">
+ <grid row="2" column="0" row-span="1" col-span="4" vsize-policy="0" hsize-policy="2" anchor="0" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="10"/>
</grid>
</constraints>
@@ -39,38 +23,23 @@
<JEditorPane.honorDisplayProperties class="java.lang.Boolean" value="true"/>
</clientProperties>
</component>
- <component id="9edbd" class="javax.swing.JPasswordField" binding="myPasswordField">
- <constraints>
- <grid row="2" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
- <preferred-size width="150" height="-1"/>
- </grid>
- </constraints>
- <properties/>
- </component>
- <component id="8a6dd" class="javax.swing.JButton" binding="myTestButton" default-binding="true">
- <constraints>
- <grid row="3" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text value="Test"/>
- </properties>
- </component>
<vspacer id="6ace">
<constraints>
- <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
- <component id="45bab" class="javax.swing.JLabel">
+ <component id="45bab" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
+ <anchor value="e4416"/>
<text value="Host:"/>
</properties>
</component>
<component id="3352a" class="javax.swing.JTextField" binding="myHostTextField">
<constraints>
- <grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
@@ -78,10 +47,110 @@
</component>
<component id="5a680" class="com.intellij.openapi.ui.ComboBox" binding="myAuthTypeComboBox">
<constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="0" column="3" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
+ <grid id="bda15" binding="myCardPanel" layout-manager="CardLayout" hgap="0" vgap="0">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="5" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <grid id="e4354" layout-manager="GridLayoutManager" row-count="2" 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>
+ <card name="Password"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="c0234" class="com.intellij.ui.components.JBLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <anchor value="e4416"/>
+ <text value="Login:"/>
+ </properties>
+ </component>
+ <component id="e76ec" class="javax.swing.JTextField" binding="myLoginTextField">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="e4416" class="com.intellij.ui.components.JBLabel">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Password:"/>
+ </properties>
+ </component>
+ <component id="9edbd" class="javax.swing.JPasswordField" binding="myPasswordField" custom-create="true">
+ <constraints>
+ <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ </children>
+ </grid>
+ <grid id="6d9fb" layout-manager="GridLayoutManager" row-count="2" 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>
+ <card name="Token"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="3cdb8" class="com.intellij.ui.components.JBLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <anchor value="e4416"/>
+ <text value="Token:"/>
+ </properties>
+ </component>
+ <component id="dd543" class="javax.swing.JPasswordField" binding="myTokenField" custom-create="true">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <vspacer id="21b9e">
+ <constraints>
+ <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </vspacer>
+ </children>
+ </grid>
+ </children>
+ </grid>
+ <component id="8a6dd" class="javax.swing.JButton" binding="myTestButton" default-binding="true">
+ <constraints>
+ <grid row="2" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Test"/>
+ </properties>
+ </component>
+ <component id="b276a" class="com.intellij.ui.components.JBLabel">
+ <constraints>
+ <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Auth Type:"/>
+ </properties>
+ </component>
</children>
</grid>
</form>
diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java
index b1f08bc..365fa2f 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java
@@ -22,6 +22,7 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.HyperlinkAdapter;
+import com.intellij.ui.components.JBLabel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.util.GithubAuthData;
@@ -35,6 +36,8 @@
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.HyperlinkEvent;
+import javax.swing.text.Document;
+import javax.swing.text.PlainDocument;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
@@ -54,12 +57,13 @@
private JTextField myLoginTextField;
private JPasswordField myPasswordField;
+ private JPasswordField myTokenField;
private JTextPane mySignupTextField;
private JPanel myPane;
private JButton myTestButton;
private JTextField myHostTextField;
private ComboBox myAuthTypeComboBox;
- private JLabel myLoginLabel;
+ private JPanel myCardPanel;
private boolean myCredentialsModified;
@@ -84,18 +88,18 @@
try {
GithubUser user = GithubUtil.checkAuthData(getAuthData());
if (GithubAuthData.AuthType.TOKEN.equals(getAuthType())) {
- GithubNotifications.showInfoDialog(myPane, "Connection successful for user " + user.getLogin(), "Success");
+ GithubNotifications.showInfoDialog(myPane, "Success", "Connection successful for user " + user.getLogin());
}
else {
- GithubNotifications.showInfoDialog(myPane, "Connection successful", "Success");
+ GithubNotifications.showInfoDialog(myPane, "Success", "Connection successful");
}
}
catch (GithubAuthenticationException ex) {
- GithubNotifications.showErrorDialog(myPane, "Can't login using given credentials: " + ex.getMessage(), "Login Failure");
+ GithubNotifications.showErrorDialog(myPane, "Login Failure", "Can't login using given credentials: " + ex.getMessage());
}
catch (IOException ex) {
LOG.info(ex);
- GithubNotifications.showErrorDialog(myPane, "Can't login: " + GithubUtil.getErrorTextFromException(ex), "Login Failure");
+ GithubNotifications.showErrorDialog(myPane, "Login Failure", "Can't login: " + GithubUtil.getErrorTextFromException(ex));
}
}
});
@@ -137,14 +141,11 @@
if (e.getStateChange() == ItemEvent.SELECTED) {
String item = e.getItem().toString();
if (AUTH_PASSWORD.equals(item)) {
- myLoginLabel.setVisible(true);
- myLoginTextField.setVisible(true);
+ ((CardLayout)myCardPanel.getLayout()).show(myCardPanel, AUTH_PASSWORD);
}
else if (AUTH_TOKEN.equals(item)) {
- myLoginLabel.setVisible(false);
- myLoginTextField.setVisible(false);
+ ((CardLayout)myCardPanel.getLayout()).show(myCardPanel, AUTH_TOKEN);
}
- myPane.validate();
erasePassword();
}
}
@@ -240,5 +241,10 @@
public void resetCredentialsModification() {
myCredentialsModified = false;
}
-}
+ private void createUIComponents() {
+ Document doc = new PlainDocument();
+ myPasswordField = new JPasswordField(doc, null, 0);
+ myTokenField = new JPasswordField(doc, null, 0);
+ }
+}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthData.java b/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthData.java
index 5de9a65..63e93a6 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthData.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubAuthData.java
@@ -36,15 +36,19 @@
@NotNull private final String myHost;
@Nullable private final BasicAuth myBasicAuth;
@Nullable private final TokenAuth myTokenAuth;
+ private final boolean myUseProxy;
+
private GithubAuthData(@NotNull AuthType authType,
@NotNull String host,
@Nullable BasicAuth basicAuth,
- @Nullable TokenAuth tokenAuth) {
+ @Nullable TokenAuth tokenAuth,
+ boolean useProxy) {
myAuthType = authType;
myHost = host;
myBasicAuth = basicAuth;
myTokenAuth = tokenAuth;
+ myUseProxy = useProxy;
}
public static GithubAuthData createAnonymous() {
@@ -52,15 +56,19 @@
}
public static GithubAuthData createAnonymous(@NotNull String host) {
- return new GithubAuthData(AuthType.ANONYMOUS, host, null, null);
+ return new GithubAuthData(AuthType.ANONYMOUS, host, null, null, true);
}
public static GithubAuthData createBasicAuth(@NotNull String host, @NotNull String login, @NotNull String password) {
- return new GithubAuthData(AuthType.BASIC, host, new BasicAuth(login, password), null);
+ return new GithubAuthData(AuthType.BASIC, host, new BasicAuth(login, password), null, true);
}
public static GithubAuthData createTokenAuth(@NotNull String host, @NotNull String token) {
- return new GithubAuthData(AuthType.TOKEN, host, null, new TokenAuth(token));
+ return new GithubAuthData(AuthType.TOKEN, host, null, new TokenAuth(token), true);
+ }
+
+ public static GithubAuthData createTokenAuth(@NotNull String host, @NotNull String token, boolean useProxy) {
+ return new GithubAuthData(AuthType.TOKEN, host, null, new TokenAuth(token), useProxy);
}
@NotNull
@@ -83,6 +91,10 @@
return myTokenAuth;
}
+ public boolean isUseProxy() {
+ return myUseProxy;
+ }
+
public static class BasicAuth {
@NotNull private final String myLogin;
@NotNull private final String myPassword;
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTest.java b/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTest.java
index 0d24130..f8c9087 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTest.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTest.java
@@ -26,15 +26,9 @@
public void testSimple() throws Exception {
registerDefaultCreatePullRequestDialogHandler(myLogin1 + ":master");
- cd(myProjectRoot.getPath());
- cloneRepo();
- createBranch();
- createChanges();
-
GithubCreatePullRequestAction.createPullRequest(myProject, myProjectRoot);
checkNotification(NotificationType.INFORMATION, "Successfully created pull request", null);
- initGitChecks();
checkRemoteConfigured();
checkLastCommitPushed();
}
@@ -42,15 +36,9 @@
public void testParent() throws Exception {
registerDefaultCreatePullRequestDialogHandler(myLogin2 + ":file2");
- cd(myProjectRoot.getPath());
- cloneRepo();
- createBranch();
- createChanges();
-
GithubCreatePullRequestAction.createPullRequest(myProject, myProjectRoot);
checkNotification(NotificationType.INFORMATION, "Successfully created pull request", null);
- initGitChecks();
checkRemoteConfigured();
checkLastCommitPushed();
}
@@ -58,15 +46,9 @@
public void testCommitRef1() throws Exception {
registerDefaultCreatePullRequestDialogHandler(myLogin1 + ":refs/heads/master");
- cd(myProjectRoot.getPath());
- cloneRepo();
- createBranch();
- createChanges();
-
GithubCreatePullRequestAction.createPullRequest(myProject, myProjectRoot);
checkNotification(NotificationType.INFORMATION, "Successfully created pull request", null);
- initGitChecks();
checkRemoteConfigured();
checkLastCommitPushed();
}
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTestBase.java b/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTestBase.java
index 5058513..24bb780 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTestBase.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTestBase.java
@@ -30,6 +30,7 @@
import java.util.Random;
+import static com.intellij.dvcs.test.Executor.cd;
import static git4idea.test.GitExecutor.git;
/**
@@ -48,6 +49,12 @@
BRANCH_NAME = "branch_" + getTestName(false) + "_" + DateFormatUtil.formatDate(time).replace('/', '-') + "_" + rnd.nextLong();
registerHttpAuthService();
+
+ cd(myProjectRoot.getPath());
+ cloneRepo();
+ createBranch();
+ createChanges();
+ initGitChecks();
}
@Override
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java
index a710fc8..37f38ea 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java
@@ -246,18 +246,21 @@
public void updateWrapperControls(@Nullable String linkedProjectPath) {
if (linkedProjectPath != null && GradleUtil.isGradleWrapperDefined(linkedProjectPath)) {
- myUseWrapperButton.setText(GradleBundle.message("gradle.settings.text.use.wrapper"));
myUseWrapperButton.setEnabled(true);
+ myUseWrapperButton.setText(GradleBundle.message("gradle.settings.text.use.wrapper"));
if (getInitialSettings().isPreferLocalInstallationToWrapper()) {
+ myGradleHomePathField.setEnabled(true);
myUseLocalDistributionButton.setSelected(true);
}
else {
+ myGradleHomePathField.setEnabled(false);
myUseWrapperButton.setSelected(true);
}
}
else {
myUseWrapperButton.setText(GradleBundle.message("gradle.settings.text.use.wrapper.disabled"));
myUseWrapperButton.setEnabled(false);
+ myGradleHomePathField.setEnabled(true);
myUseLocalDistributionButton.setSelected(true);
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java
index bdf44b6..5fa7ca4 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java
@@ -15,13 +15,15 @@
*/
package org.jetbrains.plugins.gradle.service.task;
-import com.intellij.openapi.externalSystem.task.ExternalSystemTaskManager;
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
+import com.intellij.openapi.externalSystem.task.ExternalSystemTaskManager;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
+import com.intellij.util.SystemProperties;
import org.gradle.tooling.BuildLauncher;
import org.gradle.tooling.ProjectConnection;
import org.jetbrains.annotations.NotNull;
@@ -29,6 +31,8 @@
import org.jetbrains.plugins.gradle.service.project.GradleExecutionHelper;
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings;
+import java.io.File;
+import java.io.IOException;
import java.util.List;
/**
@@ -36,7 +40,7 @@
* @since 3/14/13 5:09 PM
*/
public class GradleTaskManager implements ExternalSystemTaskManager<GradleExecutionSettings> {
-
+
private final GradleExecutionHelper myHelper = new GradleExecutionHelper();
@Override
@@ -45,21 +49,33 @@
@NotNull String projectPath,
@Nullable final GradleExecutionSettings settings,
@Nullable final String vmOptions,
- @NotNull final ExternalSystemTaskNotificationListener listener) throws ExternalSystemException
- {
+ @NotNull final ExternalSystemTaskNotificationListener listener) throws ExternalSystemException {
Function<ProjectConnection, Void> f = new Function<ProjectConnection, Void>() {
@Override
public Void fun(ProjectConnection connection) {
BuildLauncher launcher = myHelper.getBuildLauncher(id, connection, settings, listener);
if (!StringUtil.isEmpty(vmOptions)) {
- assert vmOptions != null;
- launcher.setJvmArguments(vmOptions.trim());
+ try {
+ final File tempFile = FileUtil.createTempFile("init", ".gradle");
+ tempFile.deleteOnExit();
+ final String[] lines = {
+ "gradle.taskGraph.beforeTask { Task task ->",
+ " if (task instanceof JavaForkOptions) {",
+ " task.jvmArgs '" + vmOptions.trim() + '\'',
+ "}}",
+ };
+ FileUtil.writeToFile(tempFile, StringUtil.join(lines, SystemProperties.getLineSeparator()));
+ launcher.withArguments("--init-script", tempFile.getAbsolutePath());
+ }
+ catch (IOException e) {
+ throw new ExternalSystemException(e);
+ }
}
launcher.forTasks(ArrayUtil.toStringArray(taskNames));
launcher.run();
return null;
}
};
- myHelper.execute(projectPath, settings, f);
+ myHelper.execute(projectPath, settings, f);
}
}
diff --git a/plugins/groovy/resources/fileTemplates/code/New Method Body.groovy.ft b/plugins/groovy/resources/fileTemplates/code/New Method Body.groovy.ft
new file mode 100644
index 0000000..51bce14
--- /dev/null
+++ b/plugins/groovy/resources/fileTemplates/code/New Method Body.groovy.ft
@@ -0,0 +1 @@
+#if ( $RETURN_TYPE != "void" )$DEFAULT_RETURN_VALUE#end
\ No newline at end of file
diff --git a/plugins/groovy/resources/fileTemplates/code/New Method Body.groovy.html b/plugins/groovy/resources/fileTemplates/code/New Method Body.groovy.html
new file mode 100644
index 0000000..3dc9210
--- /dev/null
+++ b/plugins/groovy/resources/fileTemplates/code/New Method Body.groovy.html
@@ -0,0 +1,43 @@
+<html>
+<body>
+<table border="0" cellpadding="2" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
+ <tr>
+ <td colspan="3"><font face="verdana" size="-1">This is a built-in template used for filling the body of a Groovy method
+ each time it is generated by the program, e.g. when using the <b>Create Method from Usage</b> intention action.<br>
+ The template is editable. Along with Groovy expressions and comments, you can also use the predefined variables
+ that will be then expanded into the corresponding values.</font>
+ </td>
+ </tr>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
+ <tr>
+ <td colspan="3"><font face="verdana" size="-1">Predefined variables will take the following values:</font></td>
+ </tr>
+ <tr>
+ <td valign="top"><nobr><font face="verdana" size="-2" color="#7F0000"><b><i>${RETURN_TYPE}</i></b></font></nobr></td>
+ <td width="10"> </td>
+ <td valign="top"><font face="verdana" size="-1">a return type of a created method</font></td>
+ </tr>
+ <tr>
+ <td valign="top"><nobr><font face="verdana" size="-2" color="#7F0000"><b><i>${DEFAULT_RETURN_VALUE}</i></b></font></nobr></td>
+ <td width="10"> </td>
+ <td valign="top"><font face="verdana" size="-1">a value returned by the method by default</font></td>
+ </tr>
+ <tr>
+ <td valign="top"><nobr><font face="verdana" size="-2" color="#7F0000"><b><i>${METHOD_NAME}</i></b></font></nobr></td>
+ <td width="10"> </td>
+ <td valign="top"><font face="verdana" size="-1">name of the created method</font></td>
+ </tr>
+ <tr>
+ <td valign="top"><nobr><font face="verdana" size="-2" color="#7F0000"><b><i>${CLASS_NAME}</i></b></font></nobr></td>
+ <td width="10"> </td>
+ <td valign="top"><font face="verdana" size="-1">qualified name of the class where method is created</font></td>
+ </tr>
+ <tr>
+ <td valign="top"><nobr><font face="verdana" size="-2" color="#7F0000"><b><i>${SIMPLE_CLASS_NAME}</i></b></font></nobr></td>
+ <td width="10"> </td>
+ <td valign="top"><font face="verdana" size="-1">non-qualified name of the class where method is implemented</font></td>
+ </tr>
+</table>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index 1be7e595..65180b9 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -97,6 +97,7 @@
<membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebModuleMemberContributor"/>
<membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebJUnitTestMemberContributor"/>
+ <membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebTestNGTestMemberContributor"/>
<membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebBrowserMemberContributor"/>
<membersContributor implementation="org.jetbrains.plugins.groovy.gant.GantMemberContributor"/>
@@ -433,6 +434,7 @@
<extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyLiteralSelectioner"/>
<extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyMembersWithDocSelectioner"/>
<extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyBlockStatementsSelectioner"/>
+ <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyTypeDefinitionBodySelectioner"/>
<extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyTypeCastSelectioner"/>
<extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyDocParamsSelectioner"/>
<extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyArgListSelectioner"/>
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/GroovyTemplates.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/GroovyTemplates.java
index 8f6d087..49875ce 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/GroovyTemplates.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/GroovyTemplates.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.
@@ -15,16 +15,22 @@
*/
package org.jetbrains.plugins.groovy.actions;
+import org.jetbrains.annotations.NonNls;
+
/**
* @author Max Medvedev
*/
-public class GroovyTemplates {
- public static final String GROOVY_CLASS = "GroovyClass.groovy";
- public static final String GROOVY_INTERFACE = "GroovyInterface.groovy";
- public static final String GROOVY_ENUM = "GroovyEnum.groovy";
- public static final String GROOVY_ANNOTATION = "GroovyAnnotation.groovy";
- public static final String GROOVY_SCRIPT = "GroovyScript.groovy";
- public static final String GROOVY_DSL_SCRIPT = "GroovyDslScript.gdsl";
- public static final String GANT_SCRIPT = "GantScript.gant";
- public static final String GROOVY_SERVER_PAGE = "GroovyServerPage.gsp";
+public interface GroovyTemplates {
+ @NonNls String GROOVY_CLASS = "GroovyClass.groovy";
+ @NonNls String GROOVY_INTERFACE = "GroovyInterface.groovy";
+ @NonNls String GROOVY_ENUM = "GroovyEnum.groovy";
+ @NonNls String GROOVY_ANNOTATION = "GroovyAnnotation.groovy";
+ @NonNls String GROOVY_SCRIPT = "GroovyScript.groovy";
+ @NonNls String GROOVY_DSL_SCRIPT = "GroovyDslScript.gdsl";
+ @NonNls String GANT_SCRIPT = "GantScript.gant";
+ @NonNls String GROOVY_SERVER_PAGE = "GroovyServerPage.gsp";
+ @NonNls String GROOVY_FROM_USAGE_METHOD_BODY = "New Method Body.groovy";
+ @NonNls String GROOVY_JUNIT_TEST_METHOD_GROOVY = "Groovy JUnit Test Method.groovy";
+ @NonNls String GROOVY_JUNIT_SET_UP_METHOD_GROOVY = "Groovy JUnit SetUp Method.groovy";
+ @NonNls String GROOVY_JUNIT_TEAR_DOWN_METHOD_GROOVY = "Groovy JUnit TearDown Method.groovy";
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrAliasAnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrAliasAnnotationChecker.java
index fc1071d..d970970 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrAliasAnnotationChecker.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrAliasAnnotationChecker.java
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.groovy.annotator;
import com.intellij.lang.annotation.AnnotationHolder;
+import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
@@ -39,7 +40,7 @@
@Override
public boolean checkApplicability(@NotNull AnnotationHolder holder, @NotNull GrAnnotation annotation) {
- final GrAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector(annotation);
+ final PsiAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector(annotation);
if (annotationCollector == null) {
return false;
}
@@ -62,7 +63,7 @@
@Override
public boolean checkArgumentList(@NotNull AnnotationHolder holder, @NotNull GrAnnotation annotation) {
- final GrAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector(annotation);
+ final PsiAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector(annotation);
if (annotationCollector == null) {
return false;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/elements/DMethodElement.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/elements/DMethodElement.java
index c86109e..edf4bf6 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/elements/DMethodElement.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/elements/DMethodElement.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.
@@ -56,7 +56,7 @@
if (myImplicitMethod != null) return myImplicitMethod;
Boolean aStatic = isStatic();
- myImplicitMethod = new GrDynamicImplicitMethod(manager, getName(), containingClassName, aStatic != null && aStatic.booleanValue(), myPairs);
+ myImplicitMethod = new GrDynamicImplicitMethod(manager, getName(), containingClassName, aStatic != null && aStatic.booleanValue(), myPairs, getType());
return myImplicitMethod;
}
}
\ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/ui/DynamicMethodDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/ui/DynamicMethodDialog.java
index 62dc064..5883cfe 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/ui/DynamicMethodDialog.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/dynamic/ui/DynamicMethodDialog.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.
@@ -103,7 +103,7 @@
private class TypeColumnInfo extends ColumnInfo<ParamInfo, String> {
public TypeColumnInfo() {
- super(GroovyBundle.message("dynamic.name"));
+ super(GroovyBundle.message("dynamic.type"));
}
public String valueOf(ParamInfo pair) {
@@ -123,14 +123,13 @@
return;
}
- if (type == null) return;
- pair.type =type.getCanonicalText();
+ pair.type = type.getCanonicalText();
}
}
private static class NameColumnInfo extends ColumnInfo<ParamInfo, String> {
public NameColumnInfo() {
- super(GroovyBundle.message("dynamic.type"));
+ super(GroovyBundle.message("dynamic.name"));
}
public boolean isCellEditable(ParamInfo myPair) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyAccessibilityInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyAccessibilityInspection.java
index d0a1fb4..634d32e 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyAccessibilityInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyAccessibilityInspection.java
@@ -19,6 +19,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.psi.util.PsiFormatUtilBase;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
@@ -64,6 +65,7 @@
setter != null && PsiUtil.isAccessible(place, setter);
}
+ @NotNull
@Override
protected BaseInspectionVisitor buildVisitor() {
return new MyVisitor();
@@ -89,7 +91,7 @@
}
@Override
- protected GroovyFix[] buildFixes(PsiElement location) {
+ protected GroovyFix[] buildFixes(@NotNull PsiElement location) {
if (!(location instanceof GrReferenceElement || location instanceof GrConstructorCall)) {
location = location.getParent();
}
@@ -116,6 +118,7 @@
Project project = refElement.getProject();
JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
PsiModifierList modifierListCopy = facade.getElementFactory().createFieldFromText("int a;", null).getModifierList();
+ assert modifierListCopy != null;
modifierListCopy.setModifierProperty(PsiModifier.STATIC, modifierList.hasModifierProperty(PsiModifier.STATIC));
String minModifier = PsiModifier.PROTECTED;
if (refElement.hasModifierProperty(PsiModifier.PROTECTED)) {
@@ -188,11 +191,11 @@
registerError(refElement,
PsiFormatUtil.formatMethod((PsiMethod)constructor, PsiSubstitutor.EMPTY,
- PsiFormatUtil.SHOW_NAME |
- PsiFormatUtil.SHOW_TYPE |
- PsiFormatUtil.TYPE_AFTER |
- PsiFormatUtil.SHOW_PARAMETERS,
- PsiFormatUtil.SHOW_TYPE
+ PsiFormatUtilBase.SHOW_NAME |
+ PsiFormatUtilBase.SHOW_TYPE |
+ PsiFormatUtilBase.TYPE_AFTER |
+ PsiFormatUtilBase.SHOW_PARAMETERS,
+ PsiFormatUtilBase.SHOW_TYPE
));
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/control/finalVar/GrFinalVariableAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/control/finalVar/GrFinalVariableAccessInspection.java
index f988749..c86790d 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/control/finalVar/GrFinalVariableAccessInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/control/finalVar/GrFinalVariableAccessInspection.java
@@ -27,6 +27,7 @@
import org.jetbrains.plugins.groovy.GroovyBundle;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
+import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
import org.jetbrains.plugins.groovy.lang.psi.*;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
import org.jetbrains.plugins.groovy.lang.psi.api.formatter.GrControlStatement;
@@ -102,14 +103,29 @@
super.visitReferenceExpression(ref);
final PsiElement resolved = ref.resolve();
- if (resolved instanceof GrField && ((GrField)resolved).hasModifierProperty(FINAL) && PsiUtil.isLValue(ref)) {
+ if (resolved instanceof GrField && ((GrField)resolved).hasModifierProperty(FINAL)) {
final GrField field = (GrField)resolved;
-
final PsiClass containingClass = field.getContainingClass();
- if (containingClass == null || !PsiTreeUtil.isAncestor(containingClass, ref, true)) {
- registerError(ref, GroovyBundle.message("cannot.assign.a.value.to.final.field.0", field.getName()), LocalQuickFix.EMPTY_ARRAY,
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
+
+ if (PsiUtil.isLValue(ref)) {
+ if (containingClass == null || !PsiTreeUtil.isAncestor(containingClass, ref, true)) {
+ registerError(ref, GroovyBundle.message("cannot.assign.a.value.to.final.field.0", field.getName()), LocalQuickFix.EMPTY_ARRAY,
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
+ }
}
+ else if (PsiUtil.isUsedInIncOrDec(ref)) {
+ if (containingClass == null || !isInsideConstructorOrInitializer(containingClass, ref, field.hasModifierProperty(PsiModifier.STATIC))) {
+ registerError(ref, GroovyBundle.message("cannot.assign.a.value.to.final.field.0", field.getName()), LocalQuickFix.EMPTY_ARRAY,
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
+ }
+ }
+ }
+ else if (resolved instanceof GrParameter &&
+ ((GrParameter)resolved).getDeclarationScope() instanceof GrMethod &&
+ ((GrParameter)resolved).hasModifierProperty(FINAL) &&
+ PsiUtil.isUsedInIncOrDec(ref)) {
+ registerError(ref, GroovyBundle.message("cannot.assign.a.value.to.final.parameter.0", ((GrParameter)resolved).getName()),
+ LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
}
@@ -200,6 +216,19 @@
};
}
+ private static boolean isInsideConstructorOrInitializer(@NotNull PsiClass containingClass, @NotNull GrReferenceExpression place, boolean isStatic) {
+ PsiElement container = ControlFlowUtils.findControlFlowOwner(place);
+
+ PsiClass aClass = null;
+ if (!isStatic && container instanceof GrMethod && ((GrMethod)container).isConstructor()) {
+ aClass = ((GrMethod)container).getContainingClass();
+ }
+ else if (container instanceof GrClassInitializer && ((GrClassInitializer)container).isStatic() == isStatic) {
+ aClass = ((GrClassInitializer)container).getContainingClass();
+ }
+ return aClass != null && containingClass.getManager().areElementsEquivalent(aClass, containingClass);
+ }
+
@NotNull
private static List<GrField> getFinalFields(@NotNull GrTypeDefinition clazz) {
final GrField[] fields = clazz.getCodeFields();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessInspection.java
index e5621b7..985632a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessInspection.java
@@ -682,18 +682,18 @@
}
@Override
- public void register(IntentionAction action) {
+ public void register(@NotNull IntentionAction action) {
myKey = HighlightDisplayKey.find(SHORT_NAME);
QuickFixAction.registerQuickFixAction(myInfo, action, myKey);
}
@Override
- public void register(TextRange fixRange, IntentionAction action, HighlightDisplayKey key) {
+ public void register(@NotNull TextRange fixRange, @NotNull IntentionAction action, HighlightDisplayKey key) {
QuickFixAction.registerQuickFixAction(myInfo, fixRange, action, key);
}
@Override
- public void unregister(Condition<IntentionAction> condition) {
+ public void unregister(@NotNull Condition<IntentionAction> condition) {
if (myInfo != null) {
QuickFixAction.unregisterQuickFixAction(myInfo, condition);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/selection/GroovyTypeDefinitionBodySelectioner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/selection/GroovyTypeDefinitionBodySelectioner.java
new file mode 100644
index 0000000..3125606
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/selection/GroovyTypeDefinitionBodySelectioner.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 org.jetbrains.plugins.groovy.editor.selection;
+
+import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandlerBase;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody;
+import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
+
+import java.util.List;
+
+/**
+ * Created by Max Medvedev on 8/19/13
+ */
+public class GroovyTypeDefinitionBodySelectioner extends ExtendWordSelectionHandlerBase {
+ public boolean canSelect(PsiElement e) {
+ return e instanceof GrTypeDefinitionBody;
+ }
+
+ public List<TextRange> select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) {
+ List<TextRange> result = super.select(e, editorText, cursorOffset, editor);
+
+ if (e instanceof GrTypeDefinitionBody) {
+ GrTypeDefinitionBody block = ((GrTypeDefinitionBody)e);
+ int startOffset = findOpeningBrace(block);
+ int endOffset = findClosingBrace(block, startOffset);
+ TextRange range = new TextRange(startOffset, endOffset);
+ result.addAll(expandToWholeLine(editorText, range));
+ }
+ return result;
+ }
+
+ private static int findOpeningBrace(GrTypeDefinitionBody block) {
+ PsiElement lbrace = block.getLBrace();
+ if (lbrace == null) return block.getTextRange().getStartOffset();
+
+ while (PsiImplUtil.isWhiteSpace(lbrace.getNextSibling())) {
+ lbrace = lbrace.getNextSibling();
+ }
+ return lbrace.getTextRange().getEndOffset();
+ }
+
+ private static int findClosingBrace(GrTypeDefinitionBody block, int startOffset) {
+ PsiElement rbrace = block.getRBrace();
+ if (rbrace == null) return block.getTextRange().getEndOffset();
+
+ while (PsiImplUtil.isWhiteSpace(rbrace.getPrevSibling()) && rbrace.getPrevSibling().getTextRange().getStartOffset() > startOffset) {
+ rbrace = rbrace.getPrevSibling();
+ }
+
+ return rbrace.getTextRange().getStartOffset();
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/geb/GebTestNGTestMemberContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/geb/GebTestNGTestMemberContributor.java
new file mode 100644
index 0000000..627197e
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/geb/GebTestNGTestMemberContributor.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 org.jetbrains.plugins.groovy.geb;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiType;
+import com.intellij.psi.ResolveState;
+import com.intellij.psi.scope.PsiScopeProcessor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor;
+
+/**
+ * @author zolotov
+ */
+public class GebTestNGTestMemberContributor extends NonCodeMembersContributor {
+
+ @Override
+ protected String getParentClassName() {
+ return "geb.testng.GebTest";
+ }
+
+ @Override
+ public void processDynamicElements(@NotNull PsiType qualifierType,
+ PsiClass aClass,
+ PsiScopeProcessor processor,
+ PsiElement place,
+ ResolveState state) {
+ GebUtil.contributeMembersInsideTest(processor, place, state);
+ }
+
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/IntentionUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/IntentionUtils.java
index f97bfeb..5c66f97 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/IntentionUtils.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/IntentionUtils.java
@@ -19,6 +19,8 @@
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils;
import com.intellij.codeInsight.daemon.impl.quickfix.CreateMethodFromUsageFix;
import com.intellij.codeInsight.template.*;
+import com.intellij.ide.fileTemplates.FileTemplate;
+import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
@@ -30,6 +32,7 @@
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.GroovyFileType;
+import org.jetbrains.plugins.groovy.actions.GroovyTemplates;
import org.jetbrains.plugins.groovy.annotator.intentions.QuickfixUtil;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
@@ -140,7 +143,9 @@
((GrMethod)method).setReturnType(PsiType.VOID);
}
if (method.getBody() != null) {
- CreateFromUsageUtils.setupMethodBody(method);
+ FileTemplateManager templateManager = FileTemplateManager.getInstance();
+ FileTemplate fileTemplate = templateManager.getCodeTemplate(GroovyTemplates.GROOVY_FROM_USAGE_METHOD_BODY);
+ CreateFromUsageUtils.setupMethodBody(method, method.getContainingClass(), fileTemplate);
}
if (hasNoReturnType) {
((GrMethod)method).setReturnType(null);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/jarFinder/GroovyFindJarQuickFixProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/jarFinder/GroovyFindJarQuickFixProvider.java
index 15021e8..d2398de 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/jarFinder/GroovyFindJarQuickFixProvider.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/jarFinder/GroovyFindJarQuickFixProvider.java
@@ -12,7 +12,7 @@
*/
public class GroovyFindJarQuickFixProvider extends UnresolvedReferenceQuickFixProvider<GrReferenceElement> {
@Override
- public void registerFixes(GrReferenceElement ref, QuickFixActionRegistrar registrar) {
+ public void registerFixes(@NotNull GrReferenceElement ref, @NotNull QuickFixActionRegistrar registrar) {
registrar.register(new GroovyFindJarFix(ref));
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java
index 275ae14..257aec4 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java
@@ -591,7 +591,7 @@
PsiElement resolved = ref.resolve();
if (resolved instanceof PsiClass) {
- final GrAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector((PsiClass)resolved);
+ final PsiAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector((PsiClass)resolved);
if (annotationCollector != null) {
final ArrayList<GrAnnotation> annotations = ContainerUtil.newArrayList();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrReferenceListWeigher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrReferenceListWeigher.java
index c7f0b61..2205867 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrReferenceListWeigher.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrReferenceListWeigher.java
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.groovy.lang.completion.weighers;
import com.intellij.patterns.PlatformPatterns;
+import com.intellij.patterns.PsiElementPattern;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.ProximityLocation;
import com.intellij.psi.util.proximity.ReferenceListWeigher;
@@ -29,10 +30,13 @@
* @author peter
*/
public class GrReferenceListWeigher extends ReferenceListWeigher {
+ private static final PsiElementPattern.Capture<PsiElement> INSIDE_REFERENCE_LIST =
+ PlatformPatterns.psiElement().withParents(GrCodeReferenceElement.class, GrReferenceList.class);
+
@Override
protected Preference getPreferredCondition(@NotNull ProximityLocation location) {
PsiElement position = location.getPosition();
- if (PlatformPatterns.psiElement().withParents(GrCodeReferenceElement.class, GrReferenceList.class).accepts(position)) {
+ if (INSIDE_REFERENCE_LIST.accepts(position)) {
assert position != null;
GrReferenceList list = (GrReferenceList)position.getParent().getParent();
PsiElement parent = list.getParent();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java
index 6e4028d..967330d4 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java
@@ -180,7 +180,7 @@
String name = declaredName == null ? PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME : declaredName;
if (resolved instanceof PsiClass) {
- final GrAnnotation collector = GrAnnotationCollector.findAnnotationCollector((PsiClass)resolved);
+ final PsiAnnotation collector = GrAnnotationCollector.findAnnotationCollector((PsiClass)resolved);
if (collector != null) {
return multiResolveFromAlias(annotation, name, collector);
}
@@ -205,7 +205,7 @@
return results;
}
- private static GroovyResolveResult[] multiResolveFromAlias(@NotNull GrAnnotation alias, @NotNull String name, @NotNull GrAnnotation annotationCollector) {
+ private static GroovyResolveResult[] multiResolveFromAlias(@NotNull GrAnnotation alias, @NotNull String name, @NotNull PsiAnnotation annotationCollector) {
List<GroovyResolveResult> result = ContainerUtilRt.newArrayList();
List<GrAnnotation> annotations = ContainerUtilRt.newArrayList();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrAnnotationCollector.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrAnnotationCollector.java
index 8b8a825..2ddb1ef 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrAnnotationCollector.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrAnnotationCollector.java
@@ -19,13 +19,13 @@
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArrayInitializer;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationMemberValue;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightAnnotation;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
@@ -36,6 +36,7 @@
import java.util.Set;
public class GrAnnotationCollector {
+
@NotNull
public static GrAnnotation[] getResolvedAnnotations(@NotNull GrModifierList modifierList) {
final GrAnnotation[] rawAnnotations = modifierList.getRawAnnotations();
@@ -44,7 +45,7 @@
List<GrAnnotation> result = ContainerUtil.newArrayList();
for (GrAnnotation annotation : rawAnnotations) {
- final GrAnnotation annotationCollector = findAnnotationCollector(annotation);
+ final PsiAnnotation annotationCollector = findAnnotationCollector(annotation);
if (annotationCollector != null) {
collectAnnotations(result, annotation, annotationCollector);
}
@@ -59,7 +60,7 @@
private static boolean hasAliases(@NotNull GrAnnotation[] rawAnnotations) {
for (GrAnnotation annotation : rawAnnotations) {
- final GrAnnotation annotationCollector = findAnnotationCollector(annotation);
+ final PsiAnnotation annotationCollector = findAnnotationCollector(annotation);
if (annotationCollector != null) {
return true;
}
@@ -78,21 +79,19 @@
@NotNull
public static Set<String> collectAnnotations(@NotNull List<GrAnnotation> list,
@NotNull GrAnnotation alias,
- @NotNull GrAnnotation annotationCollector) {
+ @NotNull PsiAnnotation annotationCollector) {
- final GrModifierList modifierList = (GrModifierList)annotationCollector.getParent();
+ final PsiModifierList modifierList = (PsiModifierList)annotationCollector.getParent();
- Map<String, Map<String, GrAnnotationNameValuePair>> annotations = ContainerUtil.newHashMap();
- collectAliasedAnnotationsFromAnnotationCollectorValueAttribute(annotationCollector,
- (HashMap<String, Map<String, GrAnnotationNameValuePair>>)annotations);
- collectAliasedAnnotationsFromAnnotationCollectorAnnotations(modifierList,
- (HashMap<String, Map<String, GrAnnotationNameValuePair>>)annotations);
+ Map<String, Map<String, PsiNameValuePair>> annotations = ContainerUtil.newHashMap();
+ collectAliasedAnnotationsFromAnnotationCollectorValueAttribute(annotationCollector, (HashMap<String, Map<String, PsiNameValuePair>>)annotations);
+ collectAliasedAnnotationsFromAnnotationCollectorAnnotations(modifierList, (HashMap<String, Map<String, PsiNameValuePair>>)annotations);
final PsiManager manager = alias.getManager();
final GrAnnotationNameValuePair[] attributes = alias.getParameterList().getAttributes();
Set<String> allUsedAttrs = ContainerUtil.newHashSet();
- for (Map.Entry<String, Map<String, GrAnnotationNameValuePair>> entry : annotations.entrySet()) {
+ for (Map.Entry<String, Map<String, PsiNameValuePair>> entry : annotations.entrySet()) {
final String qname = entry.getKey();
final PsiClass resolved = JavaPsiFacade.getInstance(alias.getProject()).findClass(qname, alias.getResolveScope());
if (resolved == null) continue;
@@ -110,8 +109,8 @@
}
- final Map<String, GrAnnotationNameValuePair> defaults = entry.getValue();
- for (Map.Entry<String, GrAnnotationNameValuePair> defa : defaults.entrySet()) {
+ final Map<String, PsiNameValuePair> defaults = entry.getValue();
+ for (Map.Entry<String, PsiNameValuePair> defa : defaults.entrySet()) {
if (!usedAttrs.contains(defa.getKey())) {
annotation.addAttribute(defa.getValue());
}
@@ -124,16 +123,29 @@
return allUsedAttrs;
}
- private static void collectAliasedAnnotationsFromAnnotationCollectorAnnotations(@NotNull GrModifierList modifierList,
- @NotNull HashMap<String, Map<String, GrAnnotationNameValuePair>> annotations) {
- for (GrAnnotation annotation : modifierList.getRawAnnotations()) {
+ private static void collectAliasedAnnotationsFromAnnotationCollectorAnnotations(@NotNull PsiModifierList modifierList,
+ @NotNull HashMap<String, Map<String, PsiNameValuePair>> annotations) {
+ PsiElement parent = modifierList.getParent();
+ if (parent instanceof PsiClass &&
+ GroovyCommonClassNames.GROOVY_TRANSFORM_COMPILE_DYNAMIC.equals(((PsiClass)parent).getQualifiedName())) {
+ HashMap<String, PsiNameValuePair> params = ContainerUtil.newHashMap();
+ annotations.put(GroovyCommonClassNames.GROOVY_TRANSFORM_COMPILE_STATIC, params);
+ GrAnnotation annotation =
+ GroovyPsiElementFactory.getInstance(modifierList.getProject()).createAnnotationFromText("@CompileStatic(TypeCheckingMode.SKIP)");
+ params.put("value", annotation.getParameterList().getAttributes()[0]);
+ return;
+ }
+
+ PsiAnnotation[] rawAnnotations =
+ modifierList instanceof GrModifierList ? ((GrModifierList)modifierList).getRawAnnotations() : modifierList.getAnnotations();
+ for (PsiAnnotation annotation : rawAnnotations) {
final String qname = annotation.getQualifiedName();
if (qname == null || qname.equals(GroovyCommonClassNames.GROOVY_TRANSFORM_ANNOTATION_COLLECTOR)) continue;
- final GrAnnotationNameValuePair[] attributes = annotation.getParameterList().getAttributes();
- for (GrAnnotationNameValuePair pair : attributes) {
- Map<String, GrAnnotationNameValuePair> map = annotations.get(qname);
+ final PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
+ for (PsiNameValuePair pair : attributes) {
+ Map<String, PsiNameValuePair> map = annotations.get(qname);
if (map == null) {
map = ContainerUtil.newHashMap();
annotations.put(qname, map);
@@ -142,14 +154,14 @@
map.put(pair.getName() != null ? pair.getName() : "value", pair);
}
if (attributes.length == 0 && !annotations.containsKey(qname)) {
- annotations.put(qname, ContainerUtil.<String, GrAnnotationNameValuePair>newHashMap());
+ annotations.put(qname, ContainerUtil.<String, PsiNameValuePair>newHashMap());
}
}
}
- private static void collectAliasedAnnotationsFromAnnotationCollectorValueAttribute(@NotNull GrAnnotation annotationCollector,
- @NotNull HashMap<String, Map<String, GrAnnotationNameValuePair>> annotations) {
+ private static void collectAliasedAnnotationsFromAnnotationCollectorValueAttribute(@NotNull PsiAnnotation annotationCollector,
+ @NotNull HashMap<String, Map<String, PsiNameValuePair>> annotations) {
final PsiAnnotationMemberValue annotationsFromValue = annotationCollector.findAttributeValue("value");
if (annotationsFromValue instanceof GrAnnotationArrayInitializer) {
@@ -157,7 +169,7 @@
if (member instanceof GrReferenceExpression) {
final PsiElement resolved = ((GrReferenceExpression)member).resolve();
if (resolved instanceof PsiClass && ((PsiClass)resolved).isAnnotationType()) {
- annotations.put(((PsiClass)resolved).getQualifiedName(), ContainerUtil.<String, GrAnnotationNameValuePair>newHashMap());
+ annotations.put(((PsiClass)resolved).getQualifiedName(), ContainerUtil.<String, PsiNameValuePair>newHashMap());
}
}
}
@@ -165,11 +177,12 @@
}
@Nullable
- public static GrAnnotation findAnnotationCollector(@Nullable PsiClass clazz) {
- if (clazz instanceof GrTypeDefinition) {
- final GrModifierList modifierList = ((GrTypeDefinition)clazz).getModifierList();
+ public static PsiAnnotation findAnnotationCollector(@Nullable PsiClass clazz) {
+ if (clazz != null) {
+ final PsiModifierList modifierList = clazz.getModifierList();
if (modifierList != null) {
- for (GrAnnotation annotation : modifierList.getRawAnnotations()) {
+ PsiAnnotation[] annotations = modifierList instanceof GrModifierList ? ((GrModifierList)modifierList).getRawAnnotations() : modifierList.getAnnotations();
+ for (PsiAnnotation annotation : annotations) {
if (GroovyCommonClassNames.GROOVY_TRANSFORM_ANNOTATION_COLLECTOR.equals(annotation.getQualifiedName())) {
return annotation;
}
@@ -182,7 +195,7 @@
@Nullable
- public static GrAnnotation findAnnotationCollector(@NotNull GrAnnotation annotation) {
+ public static PsiAnnotation findAnnotationCollector(@NotNull GrAnnotation annotation) {
final GrCodeReferenceElement ref = annotation.getClassReference();
final PsiElement resolved = ref.resolve();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitMethod.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitMethod.java
index 0045c4c..d0ef1ca 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitMethod.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrDynamicImplicitMethod.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.
@@ -57,12 +57,14 @@
private final String myContainingClassName;
private final List<ParamInfo> myParamInfos;
+ private final String myReturnType;
public GrDynamicImplicitMethod(PsiManager manager,
String name,
String containingClassName,
boolean isStatic,
- List<ParamInfo> paramInfos) {
+ List<ParamInfo> paramInfos,
+ String returnType) {
super(manager, name);
myContainingClassName = containingClassName;
myParamInfos = paramInfos;
@@ -75,6 +77,9 @@
for (ParamInfo pair : paramInfos) {
addParameter(pair.name, pair.type, false);
}
+
+ setReturnType(returnType, getResolveScope());
+ myReturnType = returnType;
}
public String getContainingClassName() {
@@ -95,7 +100,7 @@
}
public GrDynamicImplicitMethod copy() {
- return new GrDynamicImplicitMethod(myManager, getName(), getContainingClassName(), hasModifierProperty(PsiModifier.STATIC), ContainerUtil.newArrayList(myParamInfos));
+ return new GrDynamicImplicitMethod(myManager, getName(), getContainingClassName(), hasModifierProperty(PsiModifier.STATIC), ContainerUtil.newArrayList(myParamInfos), myReturnType);
}
public boolean isValid() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightAnnotation.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightAnnotation.java
index bbf33c3..ebf4312 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightAnnotation.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightAnnotation.java
@@ -27,11 +27,14 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArgumentList;
+import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationMemberValue;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
+import org.jetbrains.plugins.groovy.refactoring.convertJavaToGroovy.AnnotationArgConverter;
import java.util.List;
@@ -89,11 +92,7 @@
@Override
public String getText() {
- StringBuilder buffer = new StringBuilder();
- buffer.append('@').append(myQualifiedName);
- buffer.append(myAnnotationArgList.getText());
-
- return buffer.toString();
+ return "@" + myQualifiedName + myAnnotationArgList.getText();
}
@Override
@@ -139,8 +138,22 @@
return null;
}
- public void addAttribute(GrAnnotationNameValuePair attribute) {
- myAnnotationArgList.addAttribute(attribute);
+ public void addAttribute(PsiNameValuePair pair) {
+ if (pair instanceof GrAnnotationNameValuePair) {
+ myAnnotationArgList.addAttribute((GrAnnotationNameValuePair)pair);
+ }
+ else {
+ GrAnnotationMemberValue newValue = new AnnotationArgConverter().convert(pair.getValue());
+ if (newValue == null) return;
+
+ String name = pair.getName();
+ GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(pair.getProject());
+ String annotationText;
+ annotationText = name != null ? "@A(" + name + "=" + newValue.getText() + ")"
+ : "@A(" + newValue.getText() + ")";
+ GrAnnotation annotation = factory.createAnnotationFromText(annotationText);
+ myAnnotationArgList.addAttribute(annotation.getParameterList().getAttributes()[0]);
+ }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java
index 6466f7d..27f597b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java
@@ -63,6 +63,7 @@
@NonNls public static final String GROOVY_LANG_NEWIFY = "groovy.lang.Newify";
@NonNls public static final String GROOVY_LANG_DELEGATES_TO = "groovy.lang.DelegatesTo";
@NonNls public static final String GROOVY_LANG_DELEGATES_TO_TARGET = "groovy.lang.DelegatesTo.Target";
+ @NonNls public static final String GROOVY_TRANSFORM_COMPILE_DYNAMIC = "groovy.transform.CompileDynamic";
private GroovyCommonClassNames() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyPropertyUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyPropertyUtils.java
index 5a1b66d..0c8f5ba 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyPropertyUtils.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyPropertyUtils.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,7 +22,6 @@
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
-import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
@@ -74,8 +73,7 @@
@Nullable
public static PsiMethod findSetterForField(PsiField field) {
final PsiClass containingClass = field.getContainingClass();
- final Project project = field.getProject();
- final String propertyName = PropertyUtil.suggestPropertyName(project, field);
+ final String propertyName = field.getName();
final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
return findPropertySetter(containingClass, propertyName, isStatic, true);
}
@@ -83,8 +81,7 @@
@Nullable
public static PsiMethod findGetterForField(PsiField field) {
final PsiClass containingClass = field.getContainingClass();
- final Project project = field.getProject();
- final String propertyName = PropertyUtil.suggestPropertyName(project, field);
+ final String propertyName = field.getName();
final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
return findPropertyGetter(containingClass, propertyName, isStatic, true);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java
index 64f8314..57d2be7 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java
@@ -836,8 +836,10 @@
}
public static boolean isAccessedForWriting(GrExpression expr) {
- if (isLValue(expr)) return true;
+ return isLValue(expr) || isUsedInIncOrDec(expr);
+ }
+ public static boolean isUsedInIncOrDec(GrExpression expr) {
PsiElement parent = PsiTreeUtil.skipParentsOfType(expr, GrParenthesizedExpression.class);
if (parent instanceof GrUnaryExpression) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java
index bfac2aa..5e2e2af 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java
@@ -25,6 +25,7 @@
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.RefactoringActionHandler;
import com.intellij.refactoring.changeSignature.ChangeSignatureHandler;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
@@ -48,7 +49,7 @@
public static final GroovyRefactoringSupportProvider INSTANCE = new GroovyRefactoringSupportProvider();
- public boolean isSafeDeleteAvailable(PsiElement element) {
+ public boolean isSafeDeleteAvailable(@NotNull PsiElement element) {
return element instanceof GrTypeDefinition ||
element instanceof GrField ||
element instanceof GrMethod;
@@ -73,7 +74,7 @@
}
@Override
- public boolean isInplaceRenameAvailable(PsiElement elementToRename, PsiElement nameSuggestionContext) {
+ public boolean isInplaceRenameAvailable(@NotNull PsiElement elementToRename, PsiElement nameSuggestionContext) {
//local vars & params renames GrVariableInplaceRenameHandler
if (nameSuggestionContext != null && nameSuggestionContext.getContainingFile() != elementToRename.getContainingFile()) return false;
@@ -93,13 +94,14 @@
}
@Override
- public boolean isInplaceIntroduceAvailable(PsiElement element, PsiElement context) {
+ public boolean isInplaceIntroduceAvailable(@NotNull PsiElement element, PsiElement context) {
if (context == null || context.getContainingFile() != element.getContainingFile()) return false;
return true;
}
@Override
- public boolean isMemberInplaceRenameAvailable(PsiElement element, PsiElement context) {
+ public boolean isMemberInplaceRenameAvailable(@NotNull PsiElement element, @Nullable PsiElement context) {
+ if (context == null) return false;
PsiElement parent = context.getParent();
//don't try to inplace rename aliased imported references
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertJavaToGroovy/AnnotationArgConverter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertJavaToGroovy/AnnotationArgConverter.java
new file mode 100644
index 0000000..7163c2f
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertJavaToGroovy/AnnotationArgConverter.java
@@ -0,0 +1,142 @@
+/*
+ * 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 org.jetbrains.plugins.groovy.refactoring.convertJavaToGroovy;
+
+import com.intellij.psi.*;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
+import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationMemberValue;
+
+/**
+ * Created by Max Medvedev on 8/19/13
+ */
+public class AnnotationArgConverter {
+ @Nullable
+ public GrAnnotationMemberValue convert(PsiAnnotationMemberValue value) {
+ final StringBuilder buffer = new StringBuilder();
+
+ buffer.append("@A(");
+ generateText(value, buffer);
+ buffer.append(")");
+
+ GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(value.getProject());
+ try {
+ return factory.createAnnotationFromText(buffer.toString()).getParameterList().getAttributes()[0].getValue();
+ }
+ catch (IncorrectOperationException e) {
+ return null;
+ }
+ }
+
+ private void generateText(PsiAnnotationMemberValue value, final StringBuilder buffer) {
+ value.accept(new JavaElementVisitor() {
+ @Override
+ public void visitAnnotation(PsiAnnotation annotation) {
+ buffer.append("@");
+ PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement();
+ if (ref == null) return;
+
+ PsiElement resolved = ref.resolve();
+
+ if (resolved instanceof PsiClass && ((PsiClass)resolved).getQualifiedName() != null) {
+ buffer.append(((PsiClass)resolved).getQualifiedName());
+ }
+ else {
+ buffer.append(ref.getText());
+ }
+
+ PsiAnnotationParameterList parameterList = annotation.getParameterList();
+ parameterList.accept(this);
+ }
+
+ @Override
+ public void visitAnnotationParameterList(PsiAnnotationParameterList list) {
+ PsiNameValuePair[] attributes = list.getAttributes();
+ if (attributes.length > 0) {
+ buffer.append('(');
+ for (PsiNameValuePair attribute : attributes) {
+ attribute.accept(this);
+ buffer.append(',');
+ }
+ buffer.replace(buffer.length() - 1, buffer.length(), ")");
+ }
+ }
+
+ @Override
+ public void visitNameValuePair(PsiNameValuePair pair) {
+ String name = pair.getName();
+ PsiAnnotationMemberValue value = pair.getValue();
+
+ if (name != null) {
+ buffer.append(name);
+ buffer.append('=');
+ }
+
+ if (value != null) {
+ value.accept(this);
+ }
+ }
+
+ @Override
+ public void visitExpression(PsiExpression expression) {
+ buffer.append(expression.getText());
+ }
+
+ @Override
+ public void visitAnnotationArrayInitializer(PsiArrayInitializerMemberValue initializer) {
+ PsiAnnotationMemberValue[] initializers = initializer.getInitializers();
+ processInitializers(initializers);
+ }
+
+ @Override
+ public void visitNewExpression(PsiNewExpression expression) {
+ PsiArrayInitializerExpression arrayInitializer = expression.getArrayInitializer();
+ if (arrayInitializer == null) {
+ super.visitNewExpression(expression);
+ }
+ else {
+ PsiType type = expression.getType();
+ if (type == null) {
+ type = PsiType.getJavaLangObject(expression.getManager(), expression.getResolveScope()).createArrayType();
+ }
+ buffer.append('(');
+ arrayInitializer.accept(this);
+ buffer.append(" as ");
+ buffer.append(type.getCanonicalText());
+ buffer.append(")");
+ }
+ }
+
+ @Override
+ public void visitArrayInitializerExpression(PsiArrayInitializerExpression arrayInitializer) {
+ processInitializers(arrayInitializer.getInitializers());
+ }
+
+ private void processInitializers(PsiAnnotationMemberValue[] initializers) {
+ buffer.append('[');
+ for (PsiAnnotationMemberValue initializer : initializers) {
+ initializer.accept(this);
+ buffer.append(',');
+ }
+ if (initializers.length > 0) {
+ buffer.delete(buffer.length() - 1, buffer.length());
+ }
+ buffer.append(']');
+ }
+ });
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceFieldIntroducer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceFieldIntroducer.java
index d765525..e915604 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceFieldIntroducer.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceFieldIntroducer.java
@@ -89,7 +89,7 @@
if (success) {
final GrVariable field = getVariable();
assert field != null;
- GrIntroduceFieldProcessor processor = new GrIntroduceFieldProcessor(generateContext(), generateSettings()) {
+ GrIntroduceFieldProcessor processor = new GrIntroduceFieldProcessor(generateContext(), generateSettings(), false) {
@NotNull
@Override
protected GrExpression getInitializer() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java
index 39413af..1081b61 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java
@@ -111,7 +111,7 @@
@Override
public GrVariable runRefactoring(@NotNull GrIntroduceContext context, @NotNull GrIntroduceFieldSettings settings) {
- return new GrIntroduceFieldProcessor(context, settings).run();
+ return new GrIntroduceFieldProcessor(context, settings, isInplace(context)).run();
}
@Override
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldProcessor.java
index 53d3d5b..3efe8f6 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldProcessor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldProcessor.java
@@ -28,6 +28,7 @@
import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
+import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
@@ -41,6 +42,7 @@
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMembersDeclaration;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
@@ -60,10 +62,12 @@
private final GrIntroduceContext context;
private final GrIntroduceFieldSettings settings;
+ private boolean myForInplacePrepare;
- public GrIntroduceFieldProcessor(@NotNull GrIntroduceContext context, @NotNull GrIntroduceFieldSettings settings) {
+ public GrIntroduceFieldProcessor(@NotNull GrIntroduceContext context, @NotNull GrIntroduceFieldSettings settings, boolean forInplacePrepare) {
this.context = context;
this.settings = settings;
+ myForInplacePrepare = forInplacePrepare;
}
public GrVariable run() {
@@ -115,7 +119,7 @@
else {
final GrExpression expression = context.getExpression();
assert expression != null;
- if (PsiUtil.isExpressionStatement(expression)) {
+ if (!myForInplacePrepare && PsiUtil.isExpressionStatement(expression)) {
expression.delete();
}
else {
@@ -181,10 +185,10 @@
final PsiElement place = context.getPlace();
final GrMember member = GrIntroduceFieldHandler.getContainer(place, scope);
- LOG.assertTrue(member != null);
- GrOpenBlock container = member instanceof GrMethod? ((GrMethod)member).getBlock():
- member instanceof GrClassInitializer ? ((GrClassInitializer)member).getBlock():
- null;
+ GrStatementOwner container = member instanceof GrMethod ? ((GrMethod)member).getBlock() :
+ member instanceof GrClassInitializer ? ((GrClassInitializer)member).getBlock() :
+ place.getContainingFile() instanceof GroovyFile ? ((GroovyFile)place.getContainingFile()) :
+ null;
assert container != null;
final GrStatement anchor;
@@ -199,35 +203,21 @@
generateAssignment(field, anchor, container);
}
- void initializeInConstructor(GrVariable field) {
+ void initializeInConstructor(@NotNull GrVariable field) {
final PsiClass scope = (PsiClass)context.getScope();
- final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(context.getProject());
if (scope instanceof GrAnonymousClassDefinition) {
- final GrClassInitializer[] initializers = ((GrAnonymousClassDefinition)scope).getInitializers();
- final GrClassInitializer initializer;
- if (initializers.length == 0) {
- initializer = (GrClassInitializer)scope.add(factory.createClassInitializer());
- }
- else {
- initializer = initializers[0];
- }
-
-
- final PsiElement anchor = findAnchorForAssignment(initializer.getBlock());
- generateAssignment(field, (GrStatement)anchor, initializer.getBlock());
- return;
+ initializeInAnonymousClassInitializer(field, (GrAnonymousClassDefinition)scope);
}
+ else {
+ initializeInConstructor(field, scope);
+ }
+ }
-
+ private void initializeInConstructor(@NotNull GrVariable field, @NotNull PsiClass scope) {
PsiMethod[] constructors = scope.getConstructors();
if (constructors.length == 0) {
- final String name = scope.getName();
- LOG.assertTrue(name != null, scope.getText());
- final GrMethod constructor =
- factory.createConstructorFromText(name, ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_STRING_ARRAY, "{}", scope);
- final PsiElement added = scope.add(constructor);
- constructors = new PsiMethod[]{(PsiMethod)added};
+ constructors = new PsiMethod[]{generateConstructor(scope)};
}
for (PsiMethod constructor : constructors) {
@@ -239,18 +229,39 @@
}
}
+ @NotNull
+ private PsiMethod generateConstructor(@NotNull PsiClass scope) {
+ final String name = scope.getName();
+ LOG.assertTrue(name != null, scope.getText());
+ GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(context.getProject());
+ final GrMethod
+ constructor = factory.createConstructorFromText(name, ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_STRING_ARRAY, "{}", scope);
+ if (scope instanceof GroovyScriptClass) constructor.getModifierList().setModifierProperty(GrModifier.DEF, true);
+ return (PsiMethod)scope.add(constructor);
+ }
+
+ private void initializeInAnonymousClassInitializer(@NotNull GrVariable field, @NotNull GrAnonymousClassDefinition scope) {
+ final GrClassInitializer[] initializers = scope.getInitializers();
+ GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(context.getProject());
+ final GrClassInitializer initializer = initializers.length == 0 ? (GrClassInitializer)scope.add(factory.createClassInitializer())
+ : initializers[0];
+
+ final PsiElement anchor = findAnchorForAssignment(initializer.getBlock());
+ generateAssignment(field, (GrStatement)anchor, initializer.getBlock());
+ }
+
private void generateAssignment(GrVariable field,
@Nullable GrStatement anchor,
- GrCodeBlock defaultContainer) {
+ GrStatementOwner defaultContainer) {
final GrExpression initializer = getInitializer();
GrAssignmentExpression init = (GrAssignmentExpression)GroovyPsiElementFactory.getInstance(context.getProject())
.createExpressionFromText(settings.getName() + " = " + initializer.getText());
- GrCodeBlock block;
+ GrStatementOwner block;
if (anchor != null) {
anchor = GroovyRefactoringUtil.addBlockIntoParent(anchor);
- LOG.assertTrue(anchor.getParent() instanceof GrCodeBlock);
- block = (GrCodeBlock)anchor.getParent();
+ LOG.assertTrue(anchor.getParent() instanceof GrStatementOwner);
+ block = (GrStatementOwner)anchor.getParent();
}
else {
block = defaultContainer;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrInplaceVariableIntroducer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrInplaceVariableIntroducer.java
index 77278f6..bbbd9a5 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrInplaceVariableIntroducer.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrInplaceVariableIntroducer.java
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.variable;
+import com.intellij.codeInsight.template.TemplateBuilderImpl;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
@@ -25,9 +26,12 @@
import com.intellij.ui.NonFocusableCheckBox;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
+import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SubtypeConstraint;
+import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrFinalListener;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrInplaceIntroducer;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext;
+import org.jetbrains.plugins.groovy.template.expressions.ChooseTypeExpression;
import javax.swing.*;
import java.awt.*;
@@ -90,4 +94,14 @@
return panel;
}
+
+ @Override
+ protected void addAdditionalVariables(TemplateBuilderImpl builder) {
+ GrVariable variable = getVariable();
+ assert variable != null;
+ TypeConstraint[] constraints = {SubtypeConstraint.create(variable.getType())};
+ ChooseTypeExpression typeExpression = new ChooseTypeExpression(constraints, variable.getManager(), true, variable.getResolveScope());
+ builder.replaceElement(variable.getTypeElementGroovy(), "Variable_type", typeExpression, true, true);
+ }
+
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
index 2aa7150..3cdabe3 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.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.
@@ -31,6 +31,7 @@
import icons.JetgroovyIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.GroovyFileType;
+import org.jetbrains.plugins.groovy.actions.GroovyTemplates;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
@@ -125,15 +126,15 @@
@Override
public FileTemplateDescriptor getSetUpMethodFileTemplateDescriptor() {
- return new FileTemplateDescriptor("Groovy JUnit SetUp Method.groovy");
+ return new FileTemplateDescriptor(GroovyTemplates.GROOVY_JUNIT_SET_UP_METHOD_GROOVY);
}
public FileTemplateDescriptor getTearDownMethodFileTemplateDescriptor() {
- return new FileTemplateDescriptor("Groovy JUnit TearDown Method.groovy");
+ return new FileTemplateDescriptor(GroovyTemplates.GROOVY_JUNIT_TEAR_DOWN_METHOD_GROOVY);
}
public FileTemplateDescriptor getTestMethodFileTemplateDescriptor() {
- return new FileTemplateDescriptor("Groovy JUnit Test Method.groovy");
+ return new FileTemplateDescriptor(GroovyTemplates.GROOVY_JUNIT_TEST_METHOD_GROOVY);
}
@Override
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/geb/GebTestsTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/geb/GebTestsTest.groovy
index c733fcf..81008c7 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/geb/GebTestsTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/geb/GebTestsTest.groovy
@@ -47,6 +47,18 @@
TestUtils.checkCompletionContains(myFixture, "\$()", "to()", "go()", "currentWindow", "verifyAt()", "title")
}
+
+ void testTestNGTestMemberCompletion() {
+ myFixture.configureByText("FooTest.groovy", """
+class FooTest extends geb.testng.GebReportingTest {
+ def testFoo() {
+ <caret>
+ }
+}
+""")
+
+ TestUtils.checkCompletionContains(myFixture, "\$()", "to()", "go()", "currentWindow", "verifyAt()", "title")
+ }
void testFieldNameCompletion() {
myFixture.configureByText("FooTest.groovy", """
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/inspections/GrFinalVariableAccessTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/inspections/GrFinalVariableAccessTest.groovy
index 564a794..60d3af34 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/inspections/GrFinalVariableAccessTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/inspections/GrFinalVariableAccessTest.groovy
@@ -508,4 +508,20 @@
}
''')
}
+
+ void testInc() {
+ testHighlighting('''\
+class Aaa {
+ final int foo = 0
+
+ def test(final String p) {
+ ++<warning>foo</warning>
+ ++<warning>p</warning>
+
+ final int i = 0
+ ++<warning>i</warning>
+ }
+}
+''')
+ }
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/aliasAnnotations/GrAnnotationHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/aliasAnnotations/GrAnnotationHighlightingTest.groovy
index 9beb849..5bc936ef 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/aliasAnnotations/GrAnnotationHighlightingTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/aliasAnnotations/GrAnnotationHighlightingTest.groovy
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.groovy.lang.aliasAnnotations
+import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection
import org.jetbrains.plugins.groovy.lang.highlighting.GrHighlightingTestBase
/**
@@ -199,4 +200,24 @@
def bbb() {}
''')
}
+
+ void testCompileDynamic() {
+ testHighlighting('''\
+import groovy.transform.CompileDynamic
+import groovy.transform.CompileStatic
+
+@CompileStatic
+class B {
+ B() {
+ println <error>x</error>
+ }
+
+ @CompileDynamic
+ def foo() {
+ println <warning>y</warning>
+ }
+}
+''', GrUnresolvedAccessInspection)
+ }
+
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrInspectionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrInspectionTest.groovy
index fe0a604..efed43e 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrInspectionTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrInspectionTest.groovy
@@ -207,6 +207,22 @@
''', GroovyAccessibilityInspection)
}
+ public void testStaticImportCapsProperty() {
+ myFixture.addFileToProject('Foo.groovy', '''\
+class Foo {
+ static def FOO = 2
+ private static def BAR = 2
+}
+''')
+ testHighlighting('''\
+import static Foo.FOO
+import static Foo.<warning descr="Access to 'BAR' exceeds its access rights">BAR</warning>
+
+print FOO + <warning descr="Access to 'BAR' exceeds its access rights">BAR</warning>
+''', GroovyAccessibilityInspection)
+ }
+
+
public void testUntypedAccess() { doTest(new GroovyUntypedAccessInspection()) }
public void testMethodMayBeStaticForCategoryClasses() {
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy
index b20ca795..92331f6 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy
@@ -1120,7 +1120,7 @@
''')
}
- void testDelegatesToApplicability() {
+ void _testDelegatesToApplicability() {
testHighlighting('''
def with(@DelegatesTo.Target Object target, @DelegatesTo Closure arg) {
arg.delegate = target
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertJavaToGroovy/ConvertAnnotationMemberValueTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertJavaToGroovy/ConvertAnnotationMemberValueTest.groovy
new file mode 100644
index 0000000..a0e3e2f
--- /dev/null
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertJavaToGroovy/ConvertAnnotationMemberValueTest.groovy
@@ -0,0 +1,66 @@
+/*
+ * 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 org.jetbrains.plugins.groovy.refactoring.convertJavaToGroovy
+
+import com.intellij.ide.highlighter.JavaFileType
+import com.intellij.psi.PsiAnnotationMemberValue
+import com.intellij.psi.PsiJavaFile
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
+import org.jetbrains.annotations.NotNull
+import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationMemberValue
+
+/**
+ * Created by Max Medvedev on 8/19/13
+ */
+class ConvertAnnotationMemberValueTest extends LightCodeInsightFixtureTestCase {
+ void testSimpleExpression1() {
+ doTest('1 + 1', '1 + 1')
+ }
+
+ void testSimpleExpression2() {
+ doTest('foo(bar)', 'foo(bar)')
+ }
+
+ void testSimpleAnnotation1() {
+ doTest('@A', '@A')
+ }
+
+ void testSimpleAnnotation2() {
+ doTest('@A()', '@A')
+ }
+
+ void testSimpleAnnotation3() {
+ doTest('@A(1, value = 2)', '@A(1,value=2)')
+ }
+
+ void testAnnotationInitializer() {
+ doTest('@A({1, 2, 3})', '@A([1,2,3])')
+ }
+
+ void testArrayInitializer() {
+ doTest('new int[]{1, 2, 3}', '([1,2,3] as int[])')
+ }
+
+ void doTest(@NotNull String java, @NotNull String expectedGroovy) {
+ myFixture.configureByText(JavaFileType.INSTANCE, '@A(' + java + ') class Clazz{}')
+
+ PsiJavaFile file = myFixture.file as PsiJavaFile
+ PsiAnnotationMemberValue value = file.classes[0].modifierList.annotations[0].parameterList.attributes[0].value
+ GrAnnotationMemberValue result = new AnnotationArgConverter().convert(value)
+
+ assertEquals(expectedGroovy, result.text)
+ }
+}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/inline/InlineVariableTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/inline/InlineVariableTest.groovy
index a0a96d2..fa46e62 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/inline/InlineVariableTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/inline/InlineVariableTest.groovy
@@ -25,7 +25,6 @@
import com.intellij.psi.impl.source.tree.TreeElement
import com.intellij.refactoring.util.CommonRefactoringUtil
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
-import junit.framework.Assert
import org.jetbrains.plugins.groovy.GroovyFileType
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable
@@ -72,7 +71,7 @@
public void testUndefinedVarInline() {doTest()}
- public void testImplicitCast() { doTest() }
+ public void testImplicitCast1() { doTest() }
public void testImplicitCast2() { doTest() }
protected void doFieldTest() {
@@ -102,13 +101,13 @@
if (selectedArea == null) {
PsiElement identifier = GroovyRefactoringUtil.findElementInRange(file, startOffset, endOffset, PsiElement.class);
if (identifier != null) {
- Assert.assertTrue("Selected area doesn't point to var", identifier.parent instanceof GrVariable);
+ assertTrue("Selected area doesn't point to var", identifier.parent instanceof GrVariable);
selectedArea = (GroovyPsiElement)identifier.parent;
}
}
- Assert.assertNotNull("Selected area reference points to nothing", selectedArea);
+ assertNotNull("Selected area reference points to nothing", selectedArea);
PsiElement element = selectedArea instanceof GrExpression ? selectedArea.reference.resolve() : selectedArea;
- Assert.assertNotNull("Cannot resolve selected reference expression", element);
+ assertNotNull("Cannot resolve selected reference expression", element);
try {
if (!inlineDef) {
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/util/TestUtils.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/util/TestUtils.java
index e9c6791..b709431 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/util/TestUtils.java
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/util/TestUtils.java
@@ -57,7 +57,7 @@
public static final String GROOVY_JAR = "groovy-all.jar";
public static final String GROOVY_JAR_17 = "groovy-all-1.7.jar";
public static final String GROOVY_JAR_18 = "groovy-1.8.0-beta-2.jar";
- public static final String GROOVY_JAR_21 = "groovy-all-2.1.0-beta-1.jar";
+ public static final String GROOVY_JAR_21 = "groovy-all-2.1.3.jar";
public static final String GROOVY_JAR_22 = "groovy-all-2.2.0-beta-1.jar";
public static String getMockJdkHome() {
diff --git a/plugins/groovy/testdata/groovy/refactoring/inlineLocal/ImplicitCast.test b/plugins/groovy/testdata/groovy/refactoring/inlineLocal/implicitCast1.test
similarity index 98%
rename from plugins/groovy/testdata/groovy/refactoring/inlineLocal/ImplicitCast.test
rename to plugins/groovy/testdata/groovy/refactoring/inlineLocal/implicitCast1.test
index 9cfa98f..e82ca12 100644
--- a/plugins/groovy/testdata/groovy/refactoring/inlineLocal/ImplicitCast.test
+++ b/plugins/groovy/testdata/groovy/refactoring/inlineLocal/implicitCast1.test
@@ -2,4 +2,4 @@
print <selection>s</selection>
-----
-print 2 as String
+print 2 as String
\ No newline at end of file
diff --git a/plugins/groovy/testdata/groovy/refactoring/inlineLocal/implicitCast2.test b/plugins/groovy/testdata/groovy/refactoring/inlineLocal/implicitCast2.test
index 871700e..a60678e 100644
--- a/plugins/groovy/testdata/groovy/refactoring/inlineLocal/implicitCast2.test
+++ b/plugins/groovy/testdata/groovy/refactoring/inlineLocal/implicitCast2.test
@@ -3,4 +3,4 @@
print <selection>s</selection>
-----
String s = 'a'
-print 2 as String
+print 2 as String
\ No newline at end of file
diff --git a/plugins/groovy/testdata/mockGeb/geb-testng-0.7.2.jar b/plugins/groovy/testdata/mockGeb/geb-testng-0.7.2.jar
new file mode 100644
index 0000000..c61f665
--- /dev/null
+++ b/plugins/groovy/testdata/mockGeb/geb-testng-0.7.2.jar
Binary files differ
diff --git a/plugins/groovy/testdata/mockGroovyLib2.1/groovy-all-2.1.0-beta-1.jar b/plugins/groovy/testdata/mockGroovyLib2.1/groovy-all-2.1.0-beta-1.jar
deleted file mode 100644
index 28ff8fd..0000000
--- a/plugins/groovy/testdata/mockGroovyLib2.1/groovy-all-2.1.0-beta-1.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/groovy/testdata/mockGroovyLib2.1/groovy-all-2.1.3.jar b/plugins/groovy/testdata/mockGroovyLib2.1/groovy-all-2.1.3.jar
new file mode 100644
index 0000000..9e434a5
--- /dev/null
+++ b/plugins/groovy/testdata/mockGroovyLib2.1/groovy-all-2.1.3.jar
Binary files differ
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java
index 13b1cc9..849305a 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java
@@ -39,7 +39,7 @@
private static final Logger LOGGER = Logger.getInstance(HgVersion.class);
private static final Pattern HG_VERSION_PATTERN =
- Pattern.compile(".+\\(\\s*\\S+\\s+(\\d+)\\.(\\d+)[\\+\\.-]?(\\d*)?.*\\s*\\)\\s*", Pattern.CASE_INSENSITIVE);
+ Pattern.compile(".+\\(\\s*\\S+\\s+(\\d+)\\.(\\d+)[\\+\\.-]?(\\d*)?.*\\s*\\)\\s*.*\\s*", Pattern.CASE_INSENSITIVE);
//f.e. Mercurial Distributed SCM (version 2.6+20130507) or Mercurial Distributed SCM (version 2.6.2), 2.7-rc+5-ca2dfc2f63eb
/**
diff --git a/plugins/hg4idea/testSrc/hg4idea/test/history/HgBrowseChangesTest.java b/plugins/hg4idea/testSrc/hg4idea/test/history/HgBrowseChangesTest.java
new file mode 100644
index 0000000..c63c715
--- /dev/null
+++ b/plugins/hg4idea/testSrc/hg4idea/test/history/HgBrowseChangesTest.java
@@ -0,0 +1,124 @@
+/*
+ * 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 hg4idea.test.history;
+
+import com.intellij.openapi.vcs.CachingCommittedChangesProvider;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
+import hg4idea.test.HgPlatformTest;
+import org.zmlx.hg4idea.HgVcs;
+import org.zmlx.hg4idea.execution.HgCommandException;
+import org.zmlx.hg4idea.provider.HgRepositoryLocation;
+
+import java.text.ParseException;
+import java.util.List;
+
+import static com.intellij.dvcs.test.Executor.cd;
+import static com.intellij.dvcs.test.Executor.touch;
+import static hg4idea.test.HgExecutor.hg;
+
+/**
+ * @author Nadya Zabrodina
+ */
+public class HgBrowseChangesTest extends HgPlatformTest {
+
+ private HgVcs myVcs;
+ private ChangeBrowserSettings mySettings;
+ private String dateBefore;
+ private String dateAfter;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ myVcs = HgVcs.getInstance(myProject);
+ assert myVcs != null;
+ mySettings = new ChangeBrowserSettings();
+ cd(myRepository);
+ touch("f2.txt");
+ hg("add");
+ hg("commit -m add");
+ java.util.Calendar now = java.util.Calendar.getInstance();
+ dateBefore = ChangeBrowserSettings.DATE_FORMAT.format(now.getTime());
+ now.set(java.util.Calendar.YEAR, 1970);
+ dateAfter = ChangeBrowserSettings.DATE_FORMAT.format(now.getTime());
+ if (!SystemInfo.isWindows) {
+ myVcs.getGlobalSettings().setRunViaBash(true);
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ myVcs.getGlobalSettings().setRunViaBash(false);
+ super.tearDown();
+ }
+
+ public void testLogRevisionWithDataFilter() throws HgCommandException, ParseException, VcsException {
+ mySettings.USE_DATE_AFTER_FILTER = true;
+ mySettings.USE_DATE_BEFORE_FILTER = true;
+ mySettings.DATE_BEFORE = dateBefore;
+ mySettings.DATE_AFTER = dateAfter;
+ doTest();
+ }
+
+ public void testLogRevisionWithAfterDataFilter() throws HgCommandException, ParseException, VcsException {
+ mySettings.USE_DATE_AFTER_FILTER = true;
+ mySettings.DATE_AFTER = dateAfter;
+ doTest();
+ }
+
+ public void testLogRevisionWithBeforeDataFilter() throws HgCommandException, ParseException, VcsException {
+ mySettings.USE_DATE_BEFORE_FILTER = true;
+ mySettings.DATE_BEFORE = dateBefore;
+ doTest();
+ }
+
+ public void testLogRevisionWithBeforeFilter() throws HgCommandException, ParseException, VcsException {
+
+ mySettings.USE_CHANGE_BEFORE_FILTER = true;
+ mySettings.CHANGE_BEFORE = "1";
+ doTest();
+ }
+
+ public void testLogRevisionWithAfterFilter() throws HgCommandException, ParseException, VcsException {
+ mySettings.USE_CHANGE_AFTER_FILTER = true;
+ mySettings.CHANGE_AFTER = "0";
+ doTest();
+ }
+
+ public void testLogRevisionWithFilter() throws HgCommandException, ParseException, VcsException {
+
+ mySettings.USE_CHANGE_BEFORE_FILTER = true;
+ mySettings.USE_CHANGE_AFTER_FILTER = true;
+ mySettings.USE_DATE_AFTER_FILTER = true;
+ mySettings.USE_DATE_BEFORE_FILTER = true;
+ mySettings.DATE_BEFORE = dateBefore;
+ mySettings.DATE_AFTER = dateAfter;
+ mySettings.CHANGE_BEFORE = "1";
+ mySettings.CHANGE_AFTER = "0";
+ doTest();
+ }
+
+ private void doTest() throws HgCommandException, VcsException {
+ CachingCommittedChangesProvider provider = myVcs.getCachingCommittedChangesProvider();
+ assert provider != null;
+ //noinspection unchecked
+ List<CommittedChangeList> revisions =
+ provider.getCommittedChanges(mySettings, new HgRepositoryLocation(myRepository.getUrl(), myRepository), -1);
+ assertTrue(!revisions.isEmpty());
+ }
+}
diff --git a/plugins/hg4idea/testSrc/hg4idea/test/history/HgLogTest.java b/plugins/hg4idea/testSrc/hg4idea/test/history/HgLogTest.java
index 4e1638e..7436367 100644
--- a/plugins/hg4idea/testSrc/hg4idea/test/history/HgLogTest.java
+++ b/plugins/hg4idea/testSrc/hg4idea/test/history/HgLogTest.java
@@ -33,20 +33,21 @@
public void testParseCopiedWithoutBraces() throws HgCommandException {
parseCopied("f.txt");
+ if (!SystemInfo.isWindows) {
+ myVcs.getGlobalSettings().setRunViaBash(true);
+ try {
+ parseCopied("f1.txt");
+ }
+ finally {
+ myVcs.getGlobalSettings().setRunViaBash(false);
+ }
+ }
}
public void testParseCopiedWithBraces() throws HgCommandException {
parseCopied("(f.txt)");
}
- public void testLogCommandViaBash() throws HgCommandException {
- if (SystemInfo.isWindows) {
- return;
- }
- myVcs.getGlobalSettings().setRunViaBash(true);
- parseCopied("f.txt");
- }
-
public void testParseFileCopiesWithWhitespaces() {
Map<String, String> filesMap = HgLogCommand.parseCopiesFileList("/a/b c/d.txt (a/b a/d.txt)\u0001/a/b c/(d).txt (/a/b c/(f).txt)");
assertTrue(filesMap.containsKey("a/b a/d.txt"));
diff --git a/plugins/hg4idea/testSrc/hg4idea/test/version/HgVersionTest.java b/plugins/hg4idea/testSrc/hg4idea/test/version/HgVersionTest.java
index 9708617..a28f3b3 100644
--- a/plugins/hg4idea/testSrc/hg4idea/test/version/HgVersionTest.java
+++ b/plugins/hg4idea/testSrc/hg4idea/test/version/HgVersionTest.java
@@ -25,6 +25,7 @@
*/
public class HgVersionTest extends HgPlatformTest {
+ //todo: should be changed to Junit Parameterized tests
private static final TestHgVersion[] commonTests = {
new TestHgVersion("Mercurial Distributed SCM (version 2.6.2)", 2, 6, 2),
new TestHgVersion("Mercurial Distributed SCM (version 2.6+20130507)", 2, 6, 20130507),
@@ -33,7 +34,10 @@
new TestHgVersion("Mercurial Distributed SCM (version 2.7-rc+5-ca2dfc2f63eb)", 2, 7, 0),
new TestHgVersion("Распределенная SCM Mercurial (версия 2.0.2)", 2, 0, 2),
new TestHgVersion("Mercurial Distributed SCM (version 2.4.2+20130102)", 2, 4, 2),
- new TestHgVersion("Распределенная SCM Mercurial (версия 2.6.1)", 2, 6, 1)
+ new TestHgVersion("Распределенная SCM Mercurial (версия 2.6.1)", 2, 6, 1),
+ new TestHgVersion("[Mercurial Distributed SCM (version 2.6.2+20130606)]", 2, 6, 2),
+ new TestHgVersion("[Mercurial Distributed SCM (version 2.4.2+20130203)]\n", 2, 4, 2),
+ new TestHgVersion("Mercurial Distributed SCM (version 2.6.2)\n", 2, 6, 2)
};
public void testParseSupported() throws Exception {
diff --git a/plugins/javaFX/javaFX.iml b/plugins/javaFX/javaFX.iml
index b56fab0..3513259 100644
--- a/plugins/javaFX/javaFX.iml
+++ b/plugins/javaFX/javaFX.iml
@@ -21,6 +21,7 @@
<orderEntry type="module" module-name="compiler-openapi" />
<orderEntry type="module" module-name="compiler-impl" />
<orderEntry type="module" module-name="common-javaFX-plugin" />
+ <orderEntry type="module" module-name="manifest" />
</component>
</module>
diff --git a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml
index f989e46..df18ddf 100644
--- a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml
+++ b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml
@@ -49,6 +49,7 @@
<referencesSearch implementation="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxControllerFieldSearcher"/>
<renamePsiElementProcessor implementation="org.jetbrains.plugins.javaFX.JavaFxRenameAttributeProcessor" order="before xmlAttribute"/>
<completion.contributor implementationClass="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxCompletionContributor" language="XML" order="before xmlNonFirst"/>
+ <manifest.parser.provider implementation="org.jetbrains.plugins.javaFX.manifest.JavaFxManifestHeaderParsers"/>
</extensions>
<actions>
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java
index 0becfab..3274603 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java
@@ -149,8 +149,8 @@
}
public static PsiClassType getPropertyClassType(PsiElement field, final String superTypeFQN) {
- if (field instanceof PsiField) {
- final PsiType type = ((PsiField)field).getType();
+ if (field instanceof PsiMember) {
+ final PsiType type = PropertyUtil.getPropertyType((PsiMember)field);
if (type instanceof PsiClassType) {
final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)type).resolveGenerics();
final PsiClass attributeClass = resolveResult.getElement();
@@ -166,6 +166,9 @@
return (PsiClassType)propertyType;
}
}
+ else {
+ return (PsiClassType)type;
+ }
}
}
}
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java
index 69cb857..41d10e4 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java
@@ -7,6 +7,7 @@
import com.intellij.util.ArrayUtil;
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.XmlElementDescriptor;
+import com.intellij.xml.impl.BasicXmlAttributeDescriptor;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.javaFX.fxml.FxmlConstants;
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
@@ -21,7 +22,7 @@
* User: anna
* Date: 1/10/13
*/
-public class JavaFxPropertyAttributeDescriptor implements XmlAttributeDescriptor {
+public class JavaFxPropertyAttributeDescriptor extends BasicXmlAttributeDescriptor {
private final String myName;
private final PsiClass myPsiClass;
@@ -62,7 +63,7 @@
@Override
public boolean isEnumerated() {
- return getEnum() != null;
+ return getEnumeratedValues() != null;
}
@Nullable
@@ -87,7 +88,7 @@
return new String[] {"true", "false"};
}
- return ArrayUtil.EMPTY_STRING_ARRAY;
+ return null;
}
protected boolean isConstant(PsiField enumField) {
@@ -99,13 +100,14 @@
return aClass != null && aClass.isEnum() ? aClass : null;
}
- public PsiField getEnumConstant(String attrValue) {
- if (isEnumerated()) {
- final PsiClass aClass = getEnum();
- final PsiField fieldByName = aClass.findFieldByName(attrValue, false);
- return fieldByName != null ? fieldByName : aClass.findFieldByName(attrValue.toUpperCase(), false);
+ @Override
+ protected PsiElement getEnumeratedValueDeclaration(XmlAttributeValue attributeValue, String value) {
+ final PsiClass aClass = getEnum();
+ if (aClass != null) {
+ final PsiField fieldByName = aClass.findFieldByName(value, false);
+ return fieldByName != null ? fieldByName : aClass.findFieldByName(value.toUpperCase(), false);
}
- return null;
+ return attributeValue;
}
@Nullable
@@ -207,6 +209,12 @@
}
@Override
+ public PsiReference[] getValueReferences(XmlAttributeValue value) {
+ String s = value.getValue();
+ return s != null && !s.startsWith("${") ? super.getValueReferences(value) : PsiReference.EMPTY_ARRAY;
+ }
+
+ @Override
public String getName(PsiElement context) {
return getName();
}
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/EnumeratedAttributeReferenceProvider.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/EnumeratedAttributeReferenceProvider.java
deleted file mode 100644
index ef72a7fb..0000000
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/EnumeratedAttributeReferenceProvider.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 org.jetbrains.plugins.javaFX.fxml.refs;
-
-import com.intellij.psi.*;
-import com.intellij.psi.xml.XmlAttribute;
-import com.intellij.psi.xml.XmlAttributeValue;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.ProcessingContext;
-import com.intellij.xml.XmlAttributeDescriptor;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.javaFX.fxml.descriptors.JavaFxPropertyAttributeDescriptor;
-
-/**
-* User: anna
-*/
-class EnumeratedAttributeReferenceProvider extends PsiReferenceProvider {
- @NotNull
- @Override
- public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
- if (element instanceof XmlAttributeValue) {
- final XmlAttributeValue xmlAttributeValue = (XmlAttributeValue)element;
- final PsiElement parent = xmlAttributeValue.getParent();
- if (parent instanceof XmlAttribute) {
- final XmlAttributeDescriptor descriptor = ((XmlAttribute)parent).getDescriptor();
- if (descriptor instanceof JavaFxPropertyAttributeDescriptor && descriptor.isEnumerated()) {
- final PsiField enumConstant = ((JavaFxPropertyAttributeDescriptor)descriptor).getEnumConstant(xmlAttributeValue.getValue());
- return new PsiReference[] {new PsiReferenceBase<XmlAttributeValue>(xmlAttributeValue){
- @Nullable
- @Override
- public PsiElement resolve() {
- return enumConstant;
- }
-
- @NotNull
- @Override
- public Object[] getVariants() {
- return ArrayUtil.EMPTY_OBJECT_ARRAY;
- }
- }};
- }
- }
- }
- return PsiReference.EMPTY_ARRAY;
- }
-}
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/FxmlReferencesContributor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/FxmlReferencesContributor.java
index d3b6a97..baaa54d 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/FxmlReferencesContributor.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/FxmlReferencesContributor.java
@@ -102,9 +102,6 @@
new ImportReferenceProvider());
registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().and(attributeValueInFxml),
- new EnumeratedAttributeReferenceProvider());
-
- registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().and(attributeValueInFxml),
new JavaFxColorReferenceProvider());
registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue()
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxAnnotator.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxAnnotator.java
index 2e04ca9..a348d38 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxAnnotator.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxAnnotator.java
@@ -63,7 +63,7 @@
if (resolve instanceof PsiMember) {
if (!JavaFxPsiUtil.isVisibleInFxml((PsiMember)resolve)) {
final String symbolPresentation = "'" + SymbolPresentationUtil.getSymbolPresentableText(resolve) + "'";
- final Annotation annotation = holder.createErrorAnnotation(element,
+ final Annotation annotation = holder.createErrorAnnotation(element,
symbolPresentation + (resolve instanceof PsiClass ? " should be public" : " should be public or annotated with @FXML"));
if (!(resolve instanceof PsiClass)) {
annotation.registerUniversalFix(new AddAnnotationFix(JavaFxCommonClassNames.JAVAFX_FXML_ANNOTATION, (PsiMember)resolve, ArrayUtil.EMPTY_STRING_ARRAY), null, null);
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReference.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReference.java
index 432e3eea..ca308cd 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReference.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReference.java
@@ -93,7 +93,7 @@
public static class JavaFxUnresolvedReferenceHandlerQuickfixProvider extends UnresolvedReferenceQuickFixProvider<JavaFxEventHandlerReference> {
@Override
- public void registerFixes(final JavaFxEventHandlerReference ref, final QuickFixActionRegistrar registrar) {
+ public void registerFixes(@NotNull final JavaFxEventHandlerReference ref, @NotNull final QuickFixActionRegistrar registrar) {
if (ref.myController != null && ref.myEventHandler == null) {
final CreateMethodQuickFix quickFix = CreateMethodQuickFix.createFix(ref.myController, getHandlerSignature(ref), "");
if (quickFix != null) {
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxTagNameReference.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxTagNameReference.java
index c7b8522..e01234f 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxTagNameReference.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxTagNameReference.java
@@ -60,7 +60,7 @@
public static class JavaFxUnresolvedTagRefsProvider extends UnresolvedReferenceQuickFixProvider<JavaFxTagNameReference> {
@Override
- public void registerFixes(JavaFxTagNameReference ref, QuickFixActionRegistrar registrar) {
+ public void registerFixes(@NotNull JavaFxTagNameReference ref, @NotNull QuickFixActionRegistrar registrar) {
XmlTag element = ref.getTagElement();
if (element != null) {
registrar.register(new JavaFxImportClassFix(ref, element) {
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/manifest/JavaFxManifestHeaderParsers.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/manifest/JavaFxManifestHeaderParsers.java
new file mode 100644
index 0000000..0151143
--- /dev/null
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/manifest/JavaFxManifestHeaderParsers.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007-2009, Osmorc Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jetbrains.plugins.javaFX.manifest;
+
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.lang.manifest.header.HeaderParser;
+import org.jetbrains.lang.manifest.header.HeaderParserProvider;
+import org.jetbrains.lang.manifest.header.impl.StandardHeaderParser;
+
+import java.util.Map;
+
+public class JavaFxManifestHeaderParsers implements HeaderParserProvider {
+ private final Map<String, HeaderParser> myParsers;
+
+ public JavaFxManifestHeaderParsers() {
+ myParsers = ContainerUtil.newHashMap();
+ myParsers.put("JavaFX-Application-Class", StandardHeaderParser.INSTANCE);
+ myParsers.put("JavaFX-Version", StandardHeaderParser.INSTANCE);
+ myParsers.put("JavaFX-Class-Path", StandardHeaderParser.INSTANCE);
+ myParsers.put("JavaFX-Preloader-Class", StandardHeaderParser.INSTANCE);
+ myParsers.put("JavaFX-Fallback-Class", StandardHeaderParser.INSTANCE);
+ }
+
+ @NotNull
+ @Override
+ public Map<String, HeaderParser> getHeaderParsers() {
+ return myParsers;
+ }
+}
diff --git a/plugins/javaFX/testData/highlighting/enumValues.fxml b/plugins/javaFX/testData/highlighting/enumValues.fxml
index 251ead1..c48b589 100644
--- a/plugins/javaFX/testData/highlighting/enumValues.fxml
+++ b/plugins/javaFX/testData/highlighting/enumValues.fxml
@@ -4,5 +4,5 @@
<?import javafx.scene.control.*?>
<GridPane xmlns:fx="http://javafx.com/fxml" alignment="center">
- <HBox alignment="<error descr="Cannot resolve symbol 'UNKNOWN'">UNKNOWN</error>"/>
+ <HBox alignment="<error descr="Wrong attribute value">UNKNOWN</error>"/>
</GridPane>
\ No newline at end of file
diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenExtensionServiceImpl.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenExtensionServiceImpl.java
index 0caff423..6b710ff 100644
--- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenExtensionServiceImpl.java
+++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/JpsMavenExtensionServiceImpl.java
@@ -78,7 +78,13 @@
@NotNull
@Override
public MavenProjectConfiguration getMavenProjectConfiguration(BuildDataPaths paths) {
- final File configFile = new File(paths.getDataStorageRoot(), MavenProjectConfiguration.CONFIGURATION_FILE_RELATIVE_PATH);
+ final File dataStorageRoot = paths.getDataStorageRoot();
+ return getMavenProjectConfiguration(dataStorageRoot);
+ }
+
+ @NotNull
+ public MavenProjectConfiguration getMavenProjectConfiguration(@NotNull File dataStorageRoot) {
+ final File configFile = new File(dataStorageRoot, MavenProjectConfiguration.CONFIGURATION_FILE_RELATIVE_PATH);
MavenProjectConfiguration config;
synchronized (myLoadedConfigs) {
config = myLoadedConfigs.get(configFile);
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/intentions/ResolveReferenceQuickFixProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/intentions/ResolveReferenceQuickFixProvider.java
index 15cb9f9..3ce874b 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/intentions/ResolveReferenceQuickFixProvider.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/intentions/ResolveReferenceQuickFixProvider.java
@@ -22,7 +22,7 @@
public class ResolveReferenceQuickFixProvider extends UnresolvedReferenceQuickFixProvider<PsiJavaCodeReferenceElement> {
- public void registerFixes(PsiJavaCodeReferenceElement ref, QuickFixActionRegistrar registrar) {
+ public void registerFixes(@NotNull PsiJavaCodeReferenceElement ref, @NotNull QuickFixActionRegistrar registrar) {
registrar.register(new AddMavenDependencyQuickFix(ref));
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/PropertiesRefactoringSupportProvider.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/PropertiesRefactoringSupportProvider.java
index fbb2454..5c3fd1f 100644
--- a/plugins/properties/src/com/intellij/lang/properties/refactoring/PropertiesRefactoringSupportProvider.java
+++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/PropertiesRefactoringSupportProvider.java
@@ -21,9 +21,10 @@
import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
public class PropertiesRefactoringSupportProvider extends RefactoringSupportProvider {
- public boolean isSafeDeleteAvailable(PsiElement element) {
+ public boolean isSafeDeleteAvailable(@NotNull PsiElement element) {
return true;
}
}
\ No newline at end of file
diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java
index dc89bb2..13b8e7d 100644
--- a/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java
+++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java
@@ -37,13 +37,25 @@
* @author Dmitry Avdeev
*/
@Tag("server")
-public abstract class TaskRepository {
+public abstract class TaskRepository {
protected static final int NO_FEATURES = 0;
public static final int BASIC_HTTP_AUTHORIZATION = 0x0001;
public static final int LOGIN_ANONYMOUSLY = 0x0002;
public static final int TIME_MANAGEMENT = 0x0004;
public static final int STATE_UPDATING = 0x0008;
+ /**
+ * Supporting this feature means that server implements some kind of issues filtering.
+ * It may be special query language like the one used in Youtrack or mere plain
+ * text search.
+ * If server supports this feature it MUST return tasks already
+ * filtered according to {@code query} parameter from {@code getIssues} method.
+ * Otherwise they will be filtered using {@code TaskSearchSupport#filterTasks}
+ *
+ * @see com.intellij.tasks.impl.TaskManagerImpl
+ * @see com.intellij.tasks.actions.TaskSearchSupport
+ */
+ public static final int NATIVE_SEARCH = 0x0010;
@Attribute("url")
public String getUrl() {
@@ -79,7 +91,8 @@
* @deprecated
* @see #createCancellableConnection()
*/
- public void testConnection() throws Exception {}
+ public void testConnection() throws Exception {
+ }
/**
* Returns an object that can test connection.
@@ -93,9 +106,10 @@
/**
* Get issues from the repository. If query is null, return issues should assigned to current user only.
+ * If server supports {@code NATIVE_SEARCH} feature, tasks returned MUST be filtered by specified query.
*
* @param query repository specific.
- * @param max maximum issues number to return
+ * @param max maximum issues number to return
* @param since last updated timestamp. If 0, all issues should be returned.
* @return found issues
* @throws Exception
@@ -228,13 +242,28 @@
public abstract void cancel();
}
- public boolean isSupported(@MagicConstant(
- flags = {NO_FEATURES, BASIC_HTTP_AUTHORIZATION, LOGIN_ANONYMOUSLY, STATE_UPDATING, TIME_MANAGEMENT}) int feature) {
+ public boolean isSupported(
+ @MagicConstant(
+ flags = {
+ NO_FEATURES,
+ BASIC_HTTP_AUTHORIZATION,
+ LOGIN_ANONYMOUSLY,
+ STATE_UPDATING,
+ TIME_MANAGEMENT,
+ NATIVE_SEARCH}
+ ) int feature) {
return (getFeatures() & feature) != 0;
}
- @MagicConstant(flags = { NO_FEATURES, BASIC_HTTP_AUTHORIZATION, LOGIN_ANONYMOUSLY, STATE_UPDATING, TIME_MANAGEMENT})
+ @MagicConstant(
+ flags = {
+ NO_FEATURES,
+ BASIC_HTTP_AUTHORIZATION,
+ LOGIN_ANONYMOUSLY,
+ STATE_UPDATING,
+ TIME_MANAGEMENT,
+ NATIVE_SEARCH})
protected int getFeatures() {
- return NO_FEATURES;
+ return NATIVE_SEARCH;
}
}
diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepositorySubtype.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepositorySubtype.java
new file mode 100644
index 0000000..e7c0991
--- /dev/null
+++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepositorySubtype.java
@@ -0,0 +1,32 @@
+/*
+ * 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.tasks;
+
+import javax.swing.*;
+
+/**
+ * This auxiliary interface was added to support creation of configured generic repositories.
+ * Every TaskRepositoryType subclass can be considered subtype of its own.
+ *
+ * @author Mikhail Golubev
+ */
+public interface TaskRepositorySubtype {
+ String getName();
+
+ Icon getIcon();
+
+ TaskRepository createRepository();
+}
diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepositoryType.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepositoryType.java
index e947be9..96f0c94 100644
--- a/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepositoryType.java
+++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepositoryType.java
@@ -23,14 +23,16 @@
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import java.util.Arrays;
import java.util.EnumSet;
+import java.util.List;
/**
* The main extension point for issue tracking integration.
*
* @author Dmitry Avdeev
*/
-public abstract class TaskRepositoryType<T extends TaskRepository> {
+public abstract class TaskRepositoryType<T extends TaskRepository> implements TaskRepositorySubtype {
public static final ExtensionPointName<TaskRepositoryType> EP_NAME = new ExtensionPointName<TaskRepositoryType>("com.intellij.tasks.repositoryType");
@@ -46,6 +48,15 @@
@NotNull
public abstract TaskRepositoryEditor createEditor(T repository, Project project, Consumer<T> changeListener);
+ public List<TaskRepositorySubtype> getAvailableSubtypes() {
+ return Arrays.asList((TaskRepositorySubtype)this);
+ }
+
+ @NotNull
+ public TaskRepository createRepository(TaskRepositorySubtype subtype) {
+ return subtype.createRepository();
+ }
+
@NotNull
public abstract TaskRepository createRepository();
diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/config/BaseRepositoryEditor.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/config/BaseRepositoryEditor.java
index c290829..d0058ec 100644
--- a/plugins/tasks/tasks-api/src/com/intellij/tasks/config/BaseRepositoryEditor.java
+++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/config/BaseRepositoryEditor.java
@@ -61,7 +61,7 @@
private JButton myProxySettingsButton;
protected JCheckBox myUseHttpAuthenticationCheckBox;
- private JPanel myCustomPanel;
+ protected JPanel myCustomPanel;
private JBCheckBox myAddCommitMessage;
private JBLabel myComment;
private JPanel myEditorPanel;
@@ -150,6 +150,16 @@
loginAnonymouslyChanged(!myLoginAnonymouslyJBCheckBox.isSelected());
}
+
+ protected final void updateCustomPanel() {
+ myCustomPanel.removeAll();
+ JComponent customPanel = createCustomPanel();
+ if (customPanel != null) {
+ myCustomPanel.add(customPanel, BorderLayout.CENTER);
+ }
+ myCustomPanel.repaint();
+ }
+
private void loginAnonymouslyChanged(boolean enabled) {
myUsernameLabel.setEnabled(enabled);
myUserNameText.setEnabled(enabled);
diff --git a/plugins/tasks/tasks-core/lib/json-path-0.8.0.jar b/plugins/tasks/tasks-core/lib/json-path-0.8.0.jar
new file mode 100644
index 0000000..e165784
--- /dev/null
+++ b/plugins/tasks/tasks-core/lib/json-path-0.8.0.jar
Binary files differ
diff --git a/plugins/tasks/tasks-core/lib/json-smart-1.1.1.jar b/plugins/tasks/tasks-core/lib/json-smart-1.1.1.jar
new file mode 100644
index 0000000..9cdad9f
--- /dev/null
+++ b/plugins/tasks/tasks-core/lib/json-smart-1.1.1.jar
Binary files differ
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.java
index 1b5ad85..e021c94 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.java
@@ -14,6 +14,7 @@
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.tasks.TaskRepositorySubtype;
import com.intellij.tasks.TaskManager;
import com.intellij.tasks.TaskRepository;
import com.intellij.tasks.TaskRepositoryType;
@@ -83,18 +84,19 @@
TaskRepositoryType[] groups = TaskManager.ourRepositoryTypes;
- final List<AnAction> createActions = ContainerUtil.map2List(groups, new Function<TaskRepositoryType, AnAction>() {
- public AnAction fun(final TaskRepositoryType group) {
- String description = "New " + group.getName() + " server";
- return new IconWithTextAction(group.getName(), description, group.getIcon()) {
+ final List<AnAction> createActions = new ArrayList<AnAction>();
+ for (final TaskRepositoryType repositoryType : groups) {
+ for (final TaskRepositorySubtype subtype : (List<TaskRepositorySubtype>)repositoryType.getAvailableSubtypes()) {
+ String description = "New " + subtype.getName() + " server";
+ createActions.add(new IconWithTextAction(subtype.getName(), description, subtype.getIcon()) {
@Override
public void actionPerformed(AnActionEvent e) {
- TaskRepository repository = group.createRepository();
+ TaskRepository repository = repositoryType.createRepository(subtype);
addRepository(repository);
}
- };
+ });
}
- });
+ }
ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(myRepositoriesList).disableUpDownActions();
@@ -110,7 +112,7 @@
if (!repositories.isEmpty()) {
group.add(Separator.getInstance());
for (final TaskRepository repository : repositories) {
- group.add(new IconWithTextAction(repository.getUrl(), repository.getUrl(), repository.getRepositoryType().getIcon()) {
+ group.add(new IconWithTextAction(repository.getUrl(), repository.getUrl(), repository.getIcon()) {
@Override
public void actionPerformed(AnActionEvent e) {
addRepository(repository);
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java
index 8245c9e..7177d44 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java
@@ -1,58 +1,83 @@
package com.intellij.tasks.generic;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.XmlElementFactory;
-import com.intellij.psi.xml.XmlTag;
import com.intellij.tasks.Task;
+import com.intellij.tasks.TaskRepositorySubtype;
import com.intellij.tasks.TaskRepositoryType;
-import com.intellij.tasks.actions.TaskSearchSupport;
import com.intellij.tasks.impl.BaseRepositoryImpl;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.net.HTTPMethod;
+import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Tag;
-import com.intellij.xml.util.XmlUtil;
-import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
-import org.apache.commons.httpclient.methods.PostMethod;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import javax.swing.*;
+import java.util.*;
+
+import static com.intellij.tasks.generic.GenericRepositoryUtil.concat;
+import static com.intellij.tasks.generic.TemplateVariable.*;
/**
- * User: Evgeny.Zakrevsky
- * Date: 10/4/12
+ * @author Evgeny.Zakrevsky
*/
@Tag("Generic")
public class GenericRepository extends BaseRepositoryImpl {
- private String myTasksListURL = "";
- private String myTaskPattern = "";
+ private static final Logger LOG = Logger.getInstance(GenericRepository.class);
+
+ public final PredefinedFactoryVariable SERVER_URL_TEMPLATE_VARIABLE = new PredefinedFactoryVariable("serverUrl") {
+ @Override
+ public String getValue() {
+ return GenericRepository.this.getUrl();
+ }
+ };
+ public final PredefinedFactoryVariable USERNAME_TEMPLATE_VARIABLE = new PredefinedFactoryVariable("username") {
+ @Override
+ public String getValue() {
+ return GenericRepository.this.getUsername();
+ }
+ };
+ public final PredefinedFactoryVariable PASSWORD_TEMPLATE_VARIABLE = new PredefinedFactoryVariable("password", true) {
+ @Override
+ public String getValue() {
+ return GenericRepository.this.getPassword();
+ }
+ };
+
+ public final List<TemplateVariable> PREDEFINED_TEMPLATE_VARIABLES = ContainerUtil.<TemplateVariable>newSmartList(
+ SERVER_URL_TEMPLATE_VARIABLE,
+ USERNAME_TEMPLATE_VARIABLE,
+ PASSWORD_TEMPLATE_VARIABLE
+ );
+
private String myLoginURL = "";
- private String myLoginMethodType = GenericRepositoryEditor.GET;
- private String myTasksListMethodType = GenericRepositoryEditor.GET;
+ private String myTasksListUrl = "";
+ private String mySingleTaskUrl;
+
+ private HTTPMethod myLoginMethodType = HTTPMethod.GET;
+ private HTTPMethod myTasksListMethodType = HTTPMethod.GET;
+ private HTTPMethod mySingleTaskMethodType = HTTPMethod.GET;
+
private ResponseType myResponseType = ResponseType.XML;
+
+ private EnumMap<ResponseType, ResponseHandler> myResponseHandlersMap = new EnumMap<ResponseType, ResponseHandler>(ResponseType.class);
+
private List<TemplateVariable> myTemplateVariables = new ArrayList<TemplateVariable>();
- final static String SERVER_URL_PLACEHOLDER = "{serverUrl}";
- final static String USERNAME_PLACEHOLDER = "{username}";
- final static String PASSWORD_PLACEHOLDER = "{password}";
- final static String ID_PLACEHOLDER = "{id}";
- final static String SUMMARY_PLACEHOLDER = "{summary}";
- final static String QUERY_PLACEHOLDER = "{query}";
- final static String MAX_COUNT_PLACEHOLDER = "{count}";
- //todo
- final static String DESCRIPTION_PLACEHOLDER = "{description}";
- //todo
- final static String PAGE_PLACEHOLDER = "{page}";
+ private String mySubtypeName;
+ /**
+ * Serialization constructor
+ */
@SuppressWarnings({"UnusedDeclaration"})
public GenericRepository() {
+ // empty
}
public GenericRepository(final TaskRepositoryType type) {
@@ -60,152 +85,43 @@
resetToDefaults();
}
+ /**
+ * Cloning constructor
+ */
public GenericRepository(final GenericRepository other) {
super(other);
- myTasksListURL = other.getTasksListURL();
- myTaskPattern = other.getTaskPattern();
- myLoginURL = other.getLoginURL();
+ myLoginURL = other.getLoginUrl();
+ myTasksListUrl = other.getTasksListUrl();
+ mySingleTaskUrl = other.getSingleTaskUrl();
+
myLoginMethodType = other.getLoginMethodType();
myTasksListMethodType = other.getTasksListMethodType();
+ mySingleTaskMethodType = other.getSingleTaskMethodType();
+
myResponseType = other.getResponseType();
myTemplateVariables = other.getTemplateVariables();
- }
-
- @Override
- public boolean isConfigured() {
- return StringUtil.isNotEmpty(myTasksListURL) && StringUtil.isNotEmpty(myTaskPattern);
- }
-
- @Override
- public Task[] getIssues(@Nullable final String query, final int max, final long since) throws Exception {
- final HttpClient httpClient = getHttpClient();
-
- if (!isLoginAnonymously() && !isUseHttpAuthentication()) login(httpClient);
-
- final HttpMethod method = getTaskListsMethod(query != null ? query : "", max);
- httpClient.executeMethod(method);
- if (method.getStatusCode() != 200) throw new Exception("Cannot get tasks: HTTP status code " + method.getStatusCode());
- final String response = method.getResponseBodyAsString();
- return parseResponse(query, max, response);
- }
-
- public Task[] parseResponse(String query, int max, String response) throws Exception {
-
- final List<String> placeholders = getPlaceholders(getTaskPattern());
- if (!placeholders.contains(ID_PLACEHOLDER) || !placeholders.contains(SUMMARY_PLACEHOLDER)) {
- throw new Exception("Incorrect Task Pattern");
+ myResponseHandlersMap = new EnumMap<ResponseType, ResponseHandler>(ResponseType.class);
+ mySubtypeName = other.mySubtypeName;
+ for (Map.Entry<ResponseType, ResponseHandler> e : other.myResponseHandlersMap.entrySet()) {
+ ResponseHandler handler = e.getValue().clone();
+ handler.setRepository(this);
+ myResponseHandlersMap.put(e.getKey(), handler);
}
-
- final String taskPatternWithoutPlaceholders = getTaskPattern().replaceAll("\\{.+?\\}", "");
- Matcher matcher = Pattern
- .compile(taskPatternWithoutPlaceholders,
- Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL | Pattern.UNICODE_CASE | Pattern.CANON_EQ)
- .matcher(response);
-
- List<Task> tasks = new ArrayList<Task>();
- while (matcher.find()) {
- String id = matcher.group(placeholders.indexOf(ID_PLACEHOLDER) + 1);
- String summary = matcher.group(placeholders.indexOf(SUMMARY_PLACEHOLDER) + 1);
- if (myResponseType == ResponseType.XML && summary != null) {
- final String finalSummary = summary;
- summary = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
- @Override
- public String compute() {
- XmlElementFactory factory = XmlElementFactory.getInstance(ProjectManager.getInstance().getDefaultProject());
- XmlTag text = factory.createTagFromText("<a>" + finalSummary + "</a>");
- return XmlUtil.decode(text.getValue().getTrimmedText());
- }
- });
- }
- tasks.add(new GenericTask(id, summary, this));
- }
-
- final boolean searchSupported = getTasksListURL().contains(QUERY_PLACEHOLDER);
- if (!searchSupported) {
- tasks = TaskSearchSupport.filterTasks(query != null ? query : "", tasks);
- }
-
- tasks = tasks.subList(0, Math.min(max, tasks.size()));
-
- return tasks.toArray(new Task[tasks.size()]);
}
- private HttpMethod getTaskListsMethod(final String query, final int max) {
- String requestUrl = getFullTasksUrl(query, max);
- final HttpMethod method =
- GenericRepositoryEditor.GET.equals(getTasksListMethodType()) ? new GetMethod(requestUrl) : getPostMethodFromURL(requestUrl);
- configureHttpMethod(method);
- return method;
- }
-
- @Override
- protected void configureHttpMethod(final HttpMethod method) {
- super.configureHttpMethod(method);
- method.addRequestHeader("accept", getResponseType().getMimeType());
- }
-
- private void login(final HttpClient httpClient) throws Exception {
- final HttpMethod method = getLoginMethod();
- httpClient.executeMethod(method);
- if (method.getStatusCode() != 200) throw new Exception("Cannot login: HTTP status code " + method.getStatusCode());
- }
-
- private HttpMethod getLoginMethod() {
- String requestUrl = getFullLoginUrl();
- return GenericRepositoryEditor.GET.equals(getLoginMethodType()) ? new GetMethod(requestUrl) : getPostMethodFromURL(requestUrl);
- }
-
- private static HttpMethod getPostMethodFromURL(final String requestUrl) {
- int n = requestUrl.indexOf('?');
- if (n == -1) {
- return new PostMethod(requestUrl);
- }
-
- PostMethod postMethod = new PostMethod(requestUrl.substring(0, n));
- n = requestUrl.indexOf('?');
- String[] requestParams = requestUrl.substring(n + 1).split("&");
- for (String requestParam : requestParams) {
- String[] nv = requestParam.split("=");
- if (nv.length == 1) {
- postMethod.addParameter(nv[0], "");
- } else {
- postMethod.addParameter(nv[0], nv[1]);
- }
- }
- return postMethod;
- }
-
- private static List<String> getPlaceholders(String value) {
- if (value == null) {
- return ContainerUtil.emptyList();
- }
-
- List<String> vars = new ArrayList<String>();
- Matcher m = Pattern.compile("\\{(.+?)\\}").matcher(value);
- while (m.find()) {
- vars.add(m.group(0));
- }
- return vars;
- }
-
- private String getFullTasksUrl(final String query, final int max) {
- return replaceTemplateVariables(getTasksListURL())
- .replaceAll(Pattern.quote(SERVER_URL_PLACEHOLDER), getUrl())
- .replaceAll(Pattern.quote(QUERY_PLACEHOLDER), encodeUrl(query))
- .replaceAll(Pattern.quote(MAX_COUNT_PLACEHOLDER), String.valueOf(max));
- }
-
- private String getFullLoginUrl() {
- return replaceTemplateVariables(getLoginURL())
- .replaceAll(Pattern.quote(SERVER_URL_PLACEHOLDER), getUrl())
- .replaceAll(Pattern.quote(USERNAME_PLACEHOLDER), encodeUrl(getUsername()))
- .replaceAll(Pattern.quote(PASSWORD_PLACEHOLDER), encodeUrl(getPassword()));
- }
-
- @Nullable
- @Override
- public Task findTask(final String id) throws Exception {
- return null;
+ public void resetToDefaults() {
+ myLoginURL = "";
+ myTasksListUrl = "";
+ mySingleTaskUrl = "";
+ myLoginMethodType = HTTPMethod.GET;
+ myTasksListMethodType = HTTPMethod.GET;
+ mySingleTaskMethodType = HTTPMethod.GET;
+ myResponseType = ResponseType.XML;
+ myTemplateVariables = new ArrayList<TemplateVariable>();
+ myResponseHandlersMap = new EnumMap<ResponseType, ResponseHandler>(ResponseType.class);
+ myResponseHandlersMap.put(ResponseType.XML, getXmlResponseHandlerDefault());
+ myResponseHandlersMap.put(ResponseType.JSON, getJsonResponseHandlerDefault());
+ myResponseHandlersMap.put(ResponseType.TEXT, getTextResponseHandlerDefault());
}
@Override
@@ -219,24 +135,100 @@
if (!(o instanceof GenericRepository)) return false;
if (!super.equals(o)) return false;
GenericRepository that = (GenericRepository)o;
- if (!Comparing.equal(getTasksListURL(), that.getTasksListURL())) return false;
- if (!Comparing.equal(getTaskPattern(), that.getTaskPattern())) return false;
- if (!Comparing.equal(getLoginURL(), that.getLoginURL())) return false;
+ if (!Comparing.equal(getLoginUrl(), that.getLoginUrl())) return false;
+ if (!Comparing.equal(getTasksListUrl(), that.getTasksListUrl())) return false;
+ if (!Comparing.equal(getSingleTaskUrl(), that.getSingleTaskUrl())) return false;
if (!Comparing.equal(getLoginMethodType(), that.getLoginMethodType())) return false;
if (!Comparing.equal(getTasksListMethodType(), that.getTasksListMethodType())) return false;
+ if (!Comparing.equal(getSingleTaskMethodType(), that.getSingleTaskMethodType())) return false;
if (!Comparing.equal(getResponseType(), that.getResponseType())) return false;
if (!Comparing.equal(getTemplateVariables(), that.getTemplateVariables())) return false;
+ if (!Comparing.equal(getResponseHandlers(), that.getResponseHandlers())) return false;
return true;
}
+ @Override
+ public boolean isConfigured() {
+ if (!super.isConfigured()) return false;
+ for (TemplateVariable variable : getTemplateVariables()) {
+ if (variable.getIsShownOnFirstTab() && StringUtil.isEmpty(variable.getValue())) {
+ return false;
+ }
+ }
+ return StringUtil.isNotEmpty(myTasksListUrl) && getActiveResponseHandler().isConfigured();
+ }
+
+ @Override
+ public Task[] getIssues(@Nullable final String query, final int max, final long since) throws Exception {
+ if (!isLoginAnonymously() && !isUseHttpAuthentication()) {
+ executeMethod(getLoginMethod());
+ }
+ List<TemplateVariable> variables = concat(getAllTemplateVariables(),
+ new TemplateVariable("max", max),
+ new TemplateVariable("since", since));
+ String requestUrl = GenericRepositoryUtil.substituteTemplateVariables(getTasksListUrl(), variables);
+ String responseBody = executeMethod(getHttpMethod(requestUrl, myTasksListMethodType));
+ Task[] tasks = getActiveResponseHandler().parseIssues(responseBody);
+ if (!StringUtil.isEmpty(mySingleTaskUrl) && !(myResponseType == ResponseType.TEXT)) {
+ for (int i = 0; i < tasks.length; i++) {
+ tasks[i] = findTask(tasks[i].getId());
+ }
+ }
+ return tasks;
+ }
+
+ private String executeMethod(HttpMethod method) throws Exception {
+ LOG.debug("URI is " + method.getURI());
+ String responseBody;
+ try {
+ getHttpClient().executeMethod(method);
+ Header contentType = method.getResponseHeader("Content-Type");
+ if (contentType != null && contentType.getValue().contains("charset")) {
+ // ISO-8859-1 if charset wasn't specified in response
+ responseBody = method.getResponseBodyAsString();
+ }
+ else {
+ responseBody = StreamUtil.readText(method.getResponseBodyAsStream(), "utf-8");
+ }
+ }
+ finally {
+ method.releaseConnection();
+ }
+ LOG.debug(responseBody);
+ LOG.debug("Status code is " + method.getStatusCode());
+ if (method.getStatusCode() != HttpStatus.SC_OK) {
+ throw new Exception("Request failed with HTTP error: " + method.getStatusText());
+ }
+ return responseBody;
+ }
+
+ private HttpMethod getHttpMethod(String requestUrl, HTTPMethod type) {
+ HttpMethod method = type == HTTPMethod.GET ? new GetMethod(requestUrl) : GenericRepositoryUtil.getPostMethodFromURL(requestUrl);
+ configureHttpMethod(method);
+ return method;
+ }
+
+ private HttpMethod getLoginMethod() {
+ String requestUrl = GenericRepositoryUtil.substituteTemplateVariables(getLoginUrl(), getAllTemplateVariables());
+ return getHttpMethod(requestUrl, myLoginMethodType);
+ }
+
+ @Nullable
+ @Override
+ public Task findTask(final String id) throws Exception {
+ List<TemplateVariable> variables = concat(getAllTemplateVariables(), new TemplateVariable("id", id));
+ String requestUrl = GenericRepositoryUtil.substituteTemplateVariables(getSingleTaskUrl(), variables);
+ HttpMethod method = getHttpMethod(requestUrl, mySingleTaskMethodType);
+ return getActiveResponseHandler().parseIssue(executeMethod(method));
+ }
+
@Nullable
@Override
public CancellableConnection createCancellableConnection() {
return new CancellableConnection() {
@Override
protected void doTest() throws Exception {
- final Task[] issues = getIssues("", 1, 0);
- if (issues.length == 0) throw new Exception("Tasks not found. Probably, you don't login.");
+ getIssues("", 1, 0);
}
@Override
@@ -245,38 +237,54 @@
};
}
- private String replaceTemplateVariables(String s) {
- String answer = new String(s);
- for (TemplateVariable templateVariable : getTemplateVariables()) {
- answer = answer.replaceAll(Pattern.quote("{" + templateVariable.getName() + "}"), templateVariable.getValue());
- }
- return answer;
+ public void setLoginUrl(final String loginUrl) {
+ myLoginURL = loginUrl;
}
- public String getLoginURL() {
+ public void setTasksListUrl(final String tasksListUrl) {
+ myTasksListUrl = tasksListUrl;
+ }
+
+ public void setSingleTaskUrl(String singleTaskUrl) {
+ mySingleTaskUrl = singleTaskUrl;
+ }
+
+ public String getLoginUrl() {
return myLoginURL;
}
- public void setLoginURL(final String loginURL) {
- myLoginURL = loginURL;
+ public String getTasksListUrl() {
+ return myTasksListUrl;
}
- public void setLoginMethodType(final String loginMethodType) {
+ public String getSingleTaskUrl() {
+ return mySingleTaskUrl;
+ }
+
+ public void setLoginMethodType(final HTTPMethod loginMethodType) {
myLoginMethodType = loginMethodType;
}
- public void setTasksListMethodType(final String tasksListMethodType) {
+ public void setTasksListMethodType(final HTTPMethod tasksListMethodType) {
myTasksListMethodType = tasksListMethodType;
}
- public String getLoginMethodType() {
+ public void setSingleTaskMethodType(HTTPMethod singleTaskMethodType) {
+ mySingleTaskMethodType = singleTaskMethodType;
+ }
+
+ public HTTPMethod getLoginMethodType() {
return myLoginMethodType;
}
- public String getTasksListMethodType() {
+ public HTTPMethod getTasksListMethodType() {
return myTasksListMethodType;
}
+ public HTTPMethod getSingleTaskMethodType() {
+ return mySingleTaskMethodType;
+ }
+
public ResponseType getResponseType() {
return myResponseType;
}
@@ -285,70 +293,91 @@
myResponseType = responseType;
}
- public String getTasksListURL() {
- return myTasksListURL;
- }
-
- public void setTasksListURL(final String tasksListURL) {
- myTasksListURL = tasksListURL;
- }
-
- public String getTaskPattern() {
- return myTaskPattern;
- }
-
- public void setTaskPattern(final String taskPattern) {
- myTaskPattern = taskPattern;
- }
-
public List<TemplateVariable> getTemplateVariables() {
return myTemplateVariables;
}
+ /**
+ * Returns all template variables including both predefined and defined by user
+ */
+ public List<TemplateVariable> getAllTemplateVariables() {
+ return ContainerUtil.concat(PREDEFINED_TEMPLATE_VARIABLES, getTemplateVariables());
+ }
+
public void setTemplateVariables(final List<TemplateVariable> templateVariables) {
myTemplateVariables = templateVariables;
}
- public void resetToDefaults() {
- myTasksListURL = getTasksListURLDefault();
- myTaskPattern = getTaskPatternDefault();
- myLoginURL = getLoginURLDefault();
- myLoginMethodType = getLoginMethodTypeDefault();
- myTasksListMethodType = getTasksListMethodTypeDefault();
- myResponseType = getResponseTypeDefault();
- myTemplateVariables = getTemplateVariablesDefault();
- }
-
- protected List<TemplateVariable> getTemplateVariablesDefault() {
- return new ArrayList<TemplateVariable>();
- }
-
- protected ResponseType getResponseTypeDefault() {
- return ResponseType.XML;
- }
-
- protected String getTasksListMethodTypeDefault() {
- return GenericRepositoryEditor.GET;
- }
-
- protected String getLoginMethodTypeDefault() {
- return GenericRepositoryEditor.GET;
- }
-
- protected String getLoginURLDefault() {
- return "";
- }
-
- protected String getTaskPatternDefault() {
- return "";
- }
-
- protected String getTasksListURLDefault() {
- return "";
+ @Override
+ public Icon getIcon() {
+ if (mySubtypeName == null) {
+ return super.getIcon();
+ }
+ @SuppressWarnings("unchecked")
+ List<TaskRepositorySubtype> subtypes = getRepositoryType().getAvailableSubtypes();
+ for (TaskRepositorySubtype s : subtypes) {
+ if (mySubtypeName.equals(s.getName())) {
+ return s.getIcon();
+ }
+ }
+ throw new AssertionError("Unknown repository subtype");
}
@Override
protected int getFeatures() {
return LOGIN_ANONYMOUSLY | BASIC_HTTP_AUTHORIZATION;
}
+
+ public ResponseHandler getResponseHandler(ResponseType type) {
+ return myResponseHandlersMap.get(type);
+ }
+
+ public ResponseHandler getActiveResponseHandler() {
+ return myResponseHandlersMap.get(myResponseType);
+ }
+
+ @AbstractCollection(
+ elementTypes = {
+ XPathResponseHandler.class,
+ JsonPathResponseHandler.class,
+ RegExResponseHandler.class
+ },
+ surroundWithTag = false
+ )
+ public List<ResponseHandler> getResponseHandlers() {
+ Collection<ResponseHandler> handlers = myResponseHandlersMap.values();
+ return new ArrayList<ResponseHandler>(handlers);
+ }
+
+ public void setResponseHandlers(List<ResponseHandler> responseHandlers) {
+ myResponseHandlersMap.clear();
+ for (ResponseHandler handler : responseHandlers) {
+ myResponseHandlersMap.put(handler.getResponseType(), handler);
+ }
+ // ResponseHandler#repository field is excluded from serialization to prevent
+ // circular dependency so it has to be done manually during serialization process
+ for (ResponseHandler handler : myResponseHandlersMap.values()) {
+ handler.setRepository(this);
+ }
+ }
+
+ public ResponseHandler getXmlResponseHandlerDefault() {
+ return new XPathResponseHandler(this);
+ }
+
+ public ResponseHandler getJsonResponseHandlerDefault() {
+ return new JsonPathResponseHandler(this);
+ }
+
+ public ResponseHandler getTextResponseHandlerDefault() {
+ return new RegExResponseHandler(this);
+ }
+
+ public String getSubtypeName() {
+ return mySubtypeName;
+ }
+
+ public void setSubtypeName(String subtypeName) {
+ mySubtypeName = subtypeName;
+ }
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.form b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.form
index a04245f..0e86957 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.form
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.form
@@ -1,149 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.tasks.generic.GenericRepositoryEditor">
- <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="8">
+ <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="6" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="8">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <xy x="20" y="20" width="500" height="400"/>
+ <xy x="20" y="20" width="500" height="438"/>
</constraints>
<properties/>
<border type="none"/>
<children>
- <grid id="5918d" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="2">
- <margin top="0" left="0" bottom="0" right="0"/>
- <constraints>
- <grid row="0" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
- </constraints>
- <properties/>
- <border type="none"/>
- <children>
- <component id="37da0" class="com.intellij.ui.components.JBLabel" binding="myLoginURLLabel">
- <constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <labelFor value="a0a2f"/>
- <text value="Lo&gin URL:"/>
- </properties>
- </component>
- <component id="a0a2f" class="com.intellij.ui.EditorTextField" binding="myLoginURLText" custom-create="true">
- <constraints>
- <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
- <preferred-size width="10" height="-1"/>
- </grid>
- </constraints>
- <properties/>
- </component>
- <component id="ce0fe" class="com.intellij.ui.components.JBLabel" binding="myLoginTooltip">
- <constraints>
- <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
- </constraints>
- <properties>
- <componentStyle value="SMALL"/>
- <fontColor value="BRIGHTER"/>
- <text value="tooltip"/>
- </properties>
- </component>
- <component id="eee0a" class="com.intellij.openapi.ui.ComboBox" binding="myLoginMethodTypeComboBox">
- <constraints>
- <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <model>
- <item value="GET"/>
- <item value="POST"/>
- </model>
- </properties>
- </component>
- </children>
- </grid>
- <grid id="294f1" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="2">
- <margin top="0" left="0" bottom="0" right="0"/>
- <constraints>
- <grid row="1" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
- </constraints>
- <properties/>
- <border type="none"/>
- <children>
- <component id="6dd8" class="com.intellij.ui.components.JBLabel">
- <constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <labelFor value="87697"/>
- <text value="Tasks &List URL:"/>
- </properties>
- </component>
- <component id="87697" class="com.intellij.ui.EditorTextField" binding="myTasksListURLText" custom-create="true">
- <constraints>
- <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
- <preferred-size width="10" height="-1"/>
- </grid>
- </constraints>
- <properties/>
- </component>
- <component id="24df4" class="com.intellij.ui.components.JBLabel" binding="myTaskListTooltip">
- <constraints>
- <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
- </constraints>
- <properties>
- <componentStyle value="SMALL"/>
- <fontColor value="BRIGHTER"/>
- <text value="tooltip"/>
- </properties>
- </component>
- <component id="d1239" class="com.intellij.openapi.ui.ComboBox" binding="myTasksListMethodTypeComboBox">
- <constraints>
- <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <model>
- <item value="GET"/>
- <item value="POST"/>
- </model>
- </properties>
- </component>
- </children>
- </grid>
- <grid id="ab85c" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="2">
- <margin top="0" left="0" bottom="0" right="0"/>
- <constraints>
- <grid row="3" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
- </constraints>
- <properties/>
- <border type="none"/>
- <children>
- <component id="8cc78" class="com.intellij.ui.components.JBLabel">
- <constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="5" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <labelFor value="a91dc"/>
- <text value="Task &Pattern:"/>
- </properties>
- </component>
- <component id="21e89" class="com.intellij.ui.components.JBLabel" binding="myTaskPatternTooltip">
- <constraints>
- <grid row="1" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
- </constraints>
- <properties>
- <componentStyle value="SMALL"/>
- <fontColor value="BRIGHTER"/>
- <text value="tooltip"/>
- </properties>
- </component>
- <component id="a91dc" class="com.intellij.ui.EditorTextField" binding="myTaskPatternText" custom-create="true">
- <constraints>
- <grid row="0" column="1" row-span="1" col-span="2" vsize-policy="7" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
- <preferred-size width="1" height="1"/>
- </grid>
- </constraints>
- <properties/>
- </component>
- </children>
- </grid>
<component id="df2e4" class="com.intellij.ui.components.JBLabel">
<constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Response Type:"/>
@@ -152,35 +19,43 @@
<grid id="d68b9" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="2" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="3" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="7c3b0" class="javax.swing.JRadioButton" binding="myXmlRadioButton">
<constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false">
+ <preferred-size width="49" height="44"/>
+ </grid>
</constraints>
<properties>
<text value="X&ML"/>
</properties>
</component>
- <component id="90539" class="javax.swing.JRadioButton" binding="myHtmlRadioButton">
+ <component id="90539" class="javax.swing.JRadioButton" binding="myTextRadioButton">
<constraints>
- <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false">
+ <preferred-size width="51" height="44"/>
+ </grid>
</constraints>
<properties>
- <text value="&HTML"/>
+ <text value="&Text"/>
</properties>
</component>
<hspacer id="cebcb">
<constraints>
- <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="14" height="44"/>
+ </grid>
</constraints>
</hspacer>
<component id="71bfc" class="javax.swing.JRadioButton" binding="myJsonRadioButton">
<constraints>
- <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false">
+ <preferred-size width="55" height="44"/>
+ </grid>
</constraints>
<properties>
<text value="JS&ON"/>
@@ -191,7 +66,7 @@
<grid id="2e934" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="4" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="5" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -227,10 +102,102 @@
</component>
</children>
</grid>
+ <grid id="ccd1b" binding="myCardPanel" layout-manager="CardLayout" hgap="0" vgap="0">
+ <constraints>
+ <grid row="4" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children/>
+ </grid>
+ <component id="4acd" class="com.intellij.ui.components.JBLabel" binding="mySingleTaskURLLabel">
+ <constraints>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <labelFor value="2b4b2"/>
+ <text value="&Single Task URL:"/>
+ </properties>
+ </component>
+ <component id="2b4b2" class="com.intellij.ui.EditorTextField" binding="mySingleTaskURLText" custom-create="true" default-binding="true">
+ <constraints>
+ <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <preferred-size width="10" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="76f26" class="com.intellij.openapi.ui.ComboBox" binding="mySingleTaskMethodComboBox">
+ <constraints>
+ <grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <model>
+ <item value="GET"/>
+ <item value="POST"/>
+ </model>
+ </properties>
+ </component>
+ <component id="6dd8" class="com.intellij.ui.components.JBLabel">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <labelFor value="87697"/>
+ <text value="Tasks &List URL:"/>
+ </properties>
+ </component>
+ <component id="87697" class="com.intellij.ui.EditorTextField" binding="myTasksListURLText" custom-create="true">
+ <constraints>
+ <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <preferred-size width="10" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="d1239" class="com.intellij.openapi.ui.ComboBox" binding="myTasksListMethodTypeComboBox">
+ <constraints>
+ <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <model>
+ <item value="GET"/>
+ <item value="POST"/>
+ </model>
+ </properties>
+ </component>
+ <component id="37da0" class="com.intellij.ui.components.JBLabel" binding="myLoginURLLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <labelFor value="a0a2f"/>
+ <text value="Lo&gin URL:"/>
+ </properties>
+ </component>
+ <component id="a0a2f" class="com.intellij.ui.EditorTextField" binding="myLoginURLText" custom-create="true">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <preferred-size width="10" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="eee0a" class="com.intellij.openapi.ui.ComboBox" binding="myLoginMethodTypeComboBox">
+ <constraints>
+ <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <model>
+ <item value="GET"/>
+ <item value="POST"/>
+ </model>
+ </properties>
+ </component>
</children>
</grid>
<buttonGroups>
- <group name="myGroup1">
+ <group name="responseTypeGroup">
<member id="7c3b0"/>
<member id="90539"/>
<member id="71bfc"/>
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java
index d1754a8..0a6b9a1 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java
@@ -1,51 +1,57 @@
package com.intellij.tasks.generic;
-import com.intellij.openapi.actionSystem.ActionManager;
-import com.intellij.openapi.actionSystem.IdeActions;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.EditorFactory;
-import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
+import com.intellij.openapi.util.Condition;
import com.intellij.tasks.TaskManager;
import com.intellij.tasks.config.BaseRepositoryEditor;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.TextFieldWithAutoCompletion;
-import com.intellij.ui.TextFieldWithAutoCompletionContributor;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.net.HTTPMethod;
+import com.intellij.util.ui.FormBuilder;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.ArrayList;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
-import static com.intellij.tasks.generic.GenericRepository.*;
+import static com.intellij.tasks.generic.GenericRepositoryUtil.concat;
+import static com.intellij.tasks.generic.GenericRepositoryUtil.createPlaceholdersList;
+import static com.intellij.tasks.generic.GenericRepositoryUtil.prettifyVariableName;
/**
- * User: Evgeny.Zakrevsky
- * Date: 10/4/12
+ * @author Evgeny.Zakrevsky
+ * @author Mikhail Golubev
*/
public class GenericRepositoryEditor<T extends GenericRepository> extends BaseRepositoryEditor<T> {
- public static final String POST = "POST";
- public static final String GET = "GET";
- private EditorTextField myTasksListURLText;
- private EditorTextField myTaskPatternText;
- protected JBLabel myLoginURLLabel;
+
protected EditorTextField myLoginURLText;
+ private EditorTextField myTasksListURLText;
+ private EditorTextField mySingleTaskURLText;
+ protected JBLabel myLoginURLLabel;
protected ComboBox myLoginMethodTypeComboBox;
private ComboBox myTasksListMethodTypeComboBox;
- private JBLabel myLoginTooltip;
- private JBLabel myTaskListTooltip;
- private JBLabel myTaskPatternTooltip;
+ private ComboBox mySingleTaskMethodComboBox;
private JPanel myPanel;
private JRadioButton myXmlRadioButton;
- private JRadioButton myHtmlRadioButton;
+ private JRadioButton myTextRadioButton;
private JButton myTest2Button;
private JRadioButton myJsonRadioButton;
private JButton myManageTemplateVariablesButton;
private JButton myResetToDefaultsButton;
+ private JPanel myCardPanel;
+ private JBLabel mySingleTaskURLLabel;
+
+ private Map<JTextField, TemplateVariable> myField2Variable;
+ private Map<JRadioButton, ResponseType> myRadio2ResponseType;
public GenericRepositoryEditor(final Project project,
final T repository,
@@ -64,7 +70,6 @@
loginUrlEnablingChanged();
}
});
-
myUseHttpAuthenticationCheckBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
@@ -72,63 +77,68 @@
}
});
- switch (myRepository.getResponseType()) {
- case XML:
- myXmlRadioButton.setSelected(true);
- myHtmlRadioButton.setSelected(false);
- myJsonRadioButton.setSelected(false);
- break;
- case HTML:
- myXmlRadioButton.setSelected(false);
- myHtmlRadioButton.setSelected(true);
- myJsonRadioButton.setSelected(false);
- break;
- case JSON:
- myXmlRadioButton.setSelected(false);
- myHtmlRadioButton.setSelected(false);
- myJsonRadioButton.setSelected(true);
- break;
- }
-
- ActionListener listener = new ActionListener() {
+ ActionListener radioButtonListener = new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
- responseTypeChanged();
+ singleTaskUrlEnablingChanged();
+ doApply();
+ selectCardByResponseType();
}
};
- myXmlRadioButton.addActionListener(listener);
- myHtmlRadioButton.addActionListener(listener);
- myJsonRadioButton.addActionListener(listener);
+ myXmlRadioButton.addActionListener(radioButtonListener);
+ myTextRadioButton.addActionListener(radioButtonListener);
+ myJsonRadioButton.addActionListener(radioButtonListener);
- myLoginMethodTypeComboBox.setSelectedItem(myRepository.getLoginMethodType());
- myTasksListMethodTypeComboBox.setSelectedItem(myRepository.getTasksListMethodType());
+ myLoginMethodTypeComboBox.setSelectedItem(myRepository.getLoginMethodType().toString());
+ myTasksListMethodTypeComboBox.setSelectedItem(myRepository.getTasksListMethodType().toString());
+ mySingleTaskMethodComboBox.setSelectedItem(myRepository.getSingleTaskMethodType().toString());
+ // set default listener updating model fields
installListener(myLoginMethodTypeComboBox);
installListener(myTasksListMethodTypeComboBox);
- installListener(myTasksListURLText.getDocument());
- installListener(myLoginURLText.getDocument());
- installListener(myTaskPatternText.getDocument());
+ installListener(mySingleTaskMethodComboBox);
+ installListener(myLoginURLText);
+ installListener(myTasksListURLText);
+ installListener(mySingleTaskURLText);
+ myTabbedPane.addTab("Server configuration", myPanel);
- String useCompletionText = ". Use " +
- KeymapUtil
- .getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_CODE_COMPLETION)) +
- " for completion.";
- myLoginTooltip.setText("<html>Available placeholders: " + SERVER_URL_PLACEHOLDER + ", " + USERNAME_PLACEHOLDER + ", " +
- PASSWORD_PLACEHOLDER + useCompletionText + "</html>");
- myTaskListTooltip.setText("<html>Available placeholders: " + SERVER_URL_PLACEHOLDER + ", " + MAX_COUNT_PLACEHOLDER + ", " +
- QUERY_PLACEHOLDER + " (use for faster tasks search)" + useCompletionText + "</html>");
- myTaskPatternTooltip.setText(
- "<html>Task pattern should be a regexp with two matching groups: ({id}.+?) and ({summary}.+?)" + useCompletionText + "</html>");
+ // Put appropriate configuration components on the card panel
+ ResponseHandler xmlHandler = myRepository.getResponseHandler(ResponseType.XML);
+ ResponseHandler jsonHandler = myRepository.getResponseHandler(ResponseType.JSON);
+ ResponseHandler textHandler = myRepository.getResponseHandler(ResponseType.TEXT);
+ // Select appropriate card pane
+ myCardPanel.add(xmlHandler.getConfigurationComponent(myProject), ResponseType.XML.getMimeType());
+ myCardPanel.add(jsonHandler.getConfigurationComponent(myProject), ResponseType.JSON.getMimeType());
+ myCardPanel.add(textHandler.getConfigurationComponent(myProject), ResponseType.TEXT.getMimeType());
- myTabbedPane.addTab("Additional", myPanel);
+ myRadio2ResponseType = new IdentityHashMap<JRadioButton, ResponseType>();
+ myRadio2ResponseType.put(myJsonRadioButton, ResponseType.JSON);
+ myRadio2ResponseType.put(myXmlRadioButton, ResponseType.XML);
+ myRadio2ResponseType.put(myTextRadioButton, ResponseType.TEXT);
myManageTemplateVariablesButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
final ManageTemplateVariablesDialog dialog = new ManageTemplateVariablesDialog(myManageTemplateVariablesButton);
- dialog.setTemplateVariables(myRepository.getTemplateVariables());
+ dialog.setTemplateVariables(myRepository.getAllTemplateVariables());
if (dialog.showAndGet()) {
- myRepository.setTemplateVariables(dialog.getTemplateVariables());
+ myRepository.setTemplateVariables(ContainerUtil.filter(dialog.getTemplateVariables(), new Condition<TemplateVariable>() {
+ @Override
+ public boolean value(TemplateVariable variable) {
+ return !variable.getIsPredefined();
+ }
+ }));
+ myCustomPanel.removeAll();
+ myCustomPanel.add(createCustomPanel());
+ //myCustomPanel.repaint();
+ myTabbedPane.getComponentAt(0).repaint();
+
+ //myLoginURLText = createEditorFieldWithPlaceholderCompletion(myRepository.getLoginUrl());
+ List<String> placeholders = createPlaceholdersList(myRepository);
+ ((TextFieldWithAutoCompletion)myLoginURLText).setVariants(placeholders);
+ ((TextFieldWithAutoCompletion)myTasksListURLText).setVariants(concat(placeholders, "{max}", "{since}"));
+ ((TextFieldWithAutoCompletion)mySingleTaskURLText).setVariants(concat(placeholders, "{id}"));
+ myPanel.repaint();
}
}
});
@@ -137,79 +147,118 @@
@Override
public void actionPerformed(final ActionEvent e) {
myRepository.resetToDefaults();
+ // XXX: Why clone() here?
reset(myRepository.clone());
}
});
+ selectRadioButtonByResponseType();
+ selectCardByResponseType();
loginUrlEnablingChanged();
+ singleTaskUrlEnablingChanged();
}
- protected void reset(final GenericRepository clone) {
- myLoginURLText.setText(clone.getLoginURL());
- myTasksListURLText.setText(clone.getTasksListURL());
- myTaskPatternText.setText(clone.getTaskPattern());
- myLoginMethodTypeComboBox.setSelectedItem(clone.getLoginMethodType());
- myTasksListMethodTypeComboBox.setSelectedItem(clone.getTasksListMethodType());
- switch (clone.getResponseType()) {
- case XML:
- myXmlRadioButton.setSelected(true);
- myHtmlRadioButton.setSelected(false);
- myJsonRadioButton.setSelected(false);
- break;
- case HTML:
- myXmlRadioButton.setSelected(false);
- myHtmlRadioButton.setSelected(true);
- myJsonRadioButton.setSelected(false);
- break;
- case JSON:
- myXmlRadioButton.setSelected(false);
- myHtmlRadioButton.setSelected(false);
- myJsonRadioButton.setSelected(true);
- break;
- }
- responseTypeChanged();
- loginUrlEnablingChanged();
- }
-
- private void responseTypeChanged() {
- doApply();
- myTaskPatternText.setFileType(myRepository.getResponseType().getFileType());
+ private void singleTaskUrlEnablingChanged() {
+ boolean enabled = !myTextRadioButton.isSelected();
+ // single task URL doesn't make sense when legacy regex handler is used
+ mySingleTaskURLText.setEnabled(enabled);
+ mySingleTaskMethodComboBox.setEnabled(enabled);
+ mySingleTaskURLLabel.setEnabled(enabled);
}
protected void loginUrlEnablingChanged() {
- final boolean enabled = !myLoginAnonymouslyJBCheckBox.isSelected() && !myUseHttpAuthenticationCheckBox.isSelected();
+ boolean enabled = !myLoginAnonymouslyJBCheckBox.isSelected() && !myUseHttpAuthenticationCheckBox.isSelected();
myLoginURLLabel.setEnabled(enabled);
myLoginURLText.setEnabled(enabled);
myLoginMethodTypeComboBox.setEnabled(enabled);
- myLoginTooltip.setEnabled(enabled);
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createCustomPanel() {
+ myField2Variable = new IdentityHashMap<JTextField, TemplateVariable>();
+ FormBuilder builder = FormBuilder.createFormBuilder();
+ for (final TemplateVariable variable : myRepository.getTemplateVariables()) {
+ if (variable.getIsShownOnFirstTab()) {
+ JTextField field = variable.getIsHidden() ? new JPasswordField(variable.getValue()) : new JTextField(variable.getValue());
+ myField2Variable.put(field, variable);
+ installListener(field);
+ JBLabel label = new JBLabel(prettifyVariableName(variable.getName()) + ":", SwingConstants.RIGHT);
+ label.setAnchor(getAnchor());
+ builder.addLabeledComponent(label, field);
+ }
+ }
+ return builder.getPanel();
+ }
+
+ protected void reset(final GenericRepository clone) {
+ myLoginURLText.setText(clone.getLoginUrl());
+ myTasksListURLText.setText(clone.getTasksListUrl());
+ mySingleTaskURLText.setText(clone.getSingleTaskUrl());
+ //myTaskPatternText.setText(clone.getTaskPattern());
+ myLoginMethodTypeComboBox.setSelectedItem(clone.getLoginMethodType());
+ myTasksListMethodTypeComboBox.setSelectedItem(clone.getTasksListMethodType());
+ mySingleTaskMethodComboBox.setSelectedItem(clone.getSingleTaskMethodType());
+ selectRadioButtonByResponseType();
+ selectCardByResponseType();
+ loginUrlEnablingChanged();
+ }
+
+ private void selectRadioButtonByResponseType() {
+ for (Map.Entry<JRadioButton, ResponseType> entry : myRadio2ResponseType.entrySet()) {
+ if (entry.getValue() == myRepository.getResponseType()) {
+ entry.getKey().setSelected(true);
+ }
+ }
+ }
+
+ private void selectCardByResponseType() {
+ CardLayout cardLayout = (CardLayout) myCardPanel.getLayout();
+ cardLayout.show(myCardPanel, myRepository.getResponseType().getMimeType());
}
@Override
public void apply() {
- myRepository.setTasksListURL(myTasksListURLText.getText());
- myRepository.setTaskPattern(myTaskPatternText.getDocument().getText());
- myRepository.setLoginURL(myLoginURLText.getText());
- myRepository.setLoginMethodType((String)myLoginMethodTypeComboBox.getModel().getSelectedItem());
- myRepository.setTasksListMethodType((String)myTasksListMethodTypeComboBox.getModel().getSelectedItem());
- myRepository.setResponseType(
- myXmlRadioButton.isSelected() ? ResponseType.XML : myJsonRadioButton.isSelected() ? ResponseType.JSON : ResponseType.HTML);
+ myRepository.setLoginUrl(myLoginURLText.getText());
+ myRepository.setTasksListUrl(myTasksListURLText.getText());
+ myRepository.setSingleTaskUrl(mySingleTaskURLText.getText());
+
+ myRepository.setLoginMethodType(HTTPMethod.valueOf((String)myLoginMethodTypeComboBox.getSelectedItem()));
+ myRepository.setTasksListMethodType(HTTPMethod.valueOf((String)myTasksListMethodTypeComboBox.getSelectedItem()));
+ myRepository.setSingleTaskMethodType(HTTPMethod.valueOf((String)mySingleTaskMethodComboBox.getSelectedItem()));
+
+ for (Map.Entry<JTextField, TemplateVariable> entry : myField2Variable.entrySet()) {
+ TemplateVariable variable = entry.getValue();
+ JTextField field = entry.getKey();
+ variable.setValue(field.getText());
+ }
+ for (Map.Entry<JRadioButton, ResponseType> entry : myRadio2ResponseType.entrySet()) {
+ if (entry.getKey().isSelected()) {
+ myRepository.setResponseType(entry.getValue());
+ }
+ }
super.apply();
}
private void createUIComponents() {
- //todo completion
- //todo completion without whitespace before cursor
- final ArrayList<String> completionList = ContainerUtil.newArrayList(SERVER_URL_PLACEHOLDER, USERNAME_PLACEHOLDER, PASSWORD_PLACEHOLDER);
- myLoginURLText = TextFieldWithAutoCompletion.create(myProject, completionList, null, false, myRepository.getLoginURL());
+ List<String> placeholders = createPlaceholdersList(myRepository);
+ myLoginURLText = createTextFieldWithCompletion(myRepository.getLoginUrl(), placeholders);
+ myTasksListURLText = createTextFieldWithCompletion(myRepository.getTasksListUrl(),
+ concat(placeholders, "{max}", "{since}"));
+ mySingleTaskURLText = createTextFieldWithCompletion(myRepository.getSingleTaskUrl(),
+ concat(placeholders, "{id}"));
+ }
- final ArrayList<String> completionList1 = ContainerUtil.newArrayList(SERVER_URL_PLACEHOLDER, QUERY_PLACEHOLDER, MAX_COUNT_PLACEHOLDER);
- myTasksListURLText = TextFieldWithAutoCompletion.create(myProject, completionList1, null, false, myRepository.getTasksListURL());
+ private TextFieldWithAutoCompletion<String> createTextFieldWithCompletion(String text, List<String> variants) {
+ return TextFieldWithAutoCompletion.create(myProject, variants, true, text);
+ }
- final Document document = EditorFactory.getInstance().createDocument(myRepository.getTaskPattern());
- myTaskPatternText = new EditorTextField(document, myProject, myRepository.getResponseType().getFileType(), false, false);
- final ArrayList<String> completionList2 = ContainerUtil.newArrayList("({id}.+?)", "({summary}.+?)");
- TextFieldWithAutoCompletionContributor
- .installCompletion(document, myProject, new TextFieldWithAutoCompletion.StringsCompletionProvider(completionList2, null), true);
- myTaskPatternText.setFontInheritedFromLAF(false);
+ @Override
+ public void setAnchor(@Nullable JComponent anchor) {
+ super.setAnchor(anchor);
+ List<JBLabel> labels = UIUtil.findComponentsOfType(myCustomPanel, JBLabel.class);
+ for (JBLabel label : labels) {
+ label.setAnchor(anchor);
+ }
}
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java
index 720afdb..1a9bb42 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java
@@ -2,19 +2,28 @@
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.tasks.TaskRepositorySubtype;
import com.intellij.tasks.TaskRepository;
import com.intellij.tasks.config.TaskRepositoryEditor;
import com.intellij.tasks.impl.BaseRepositoryType;
import com.intellij.util.Consumer;
+import com.intellij.util.xmlb.XmlSerializer;
+import icons.TasksIcons;
+import org.jdom.Document;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
/**
* User: Evgeny.Zakrevsky
* Date: 10/4/12
*/
public class GenericRepositoryType extends BaseRepositoryType<GenericRepository> {
+
@NotNull
@Override
public String getName() {
@@ -45,4 +54,61 @@
final Consumer<GenericRepository> changeListener) {
return new GenericRepositoryEditor<GenericRepository>(project, repository, changeListener);
}
+
+ @Override
+ public List<TaskRepositorySubtype> getAvailableSubtypes() {
+ return Arrays.asList(
+ this,
+ new AsanaRepository()
+ );
+ }
+
+ public class GenericSubtype implements TaskRepositorySubtype {
+ private final String myName;
+ private final Icon myIcon;
+
+ GenericSubtype(String name, Icon icon) {
+ myName = name;
+ myIcon = icon;
+ }
+
+ @Override
+ public String getName() {
+ return myName + " [G]";
+ }
+
+ @Override
+ public Icon getIcon() {
+ return myIcon;
+ }
+
+ @Override
+ public TaskRepository createRepository() {
+ Document document;
+ try {
+ String configFileName = myName.toLowerCase() + ".xml";
+ //URL resourceUrl = ResourceUtil.getResource(GenericRepositoryType.class, "connectors", configFileName);
+ URL resourceUrl = GenericRepository.class.getResource("connectors/" + configFileName);
+ if (resourceUrl == null) {
+ throw new AssertionError("Repository configuration file '" + configFileName + "' not found");
+ }
+ document = JDOMUtil.loadResourceDocument(resourceUrl);
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ GenericRepository repository = XmlSerializer.deserialize(document.getRootElement(), GenericRepository.class);
+ if (repository != null) {
+ repository.setRepositoryType(GenericRepositoryType.this);
+ repository.setSubtypeName(getName());
+ }
+ return repository;
+ }
+ }
+
+ public class AsanaRepository extends GenericSubtype {
+ public AsanaRepository() {
+ super("Asana", TasksIcons.Asana);
+ }
+ }
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryUtil.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryUtil.java
new file mode 100644
index 0000000..b90bfb83
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryUtil.java
@@ -0,0 +1,115 @@
+package com.intellij.tasks.generic;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.HashMap;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class GenericRepositoryUtil {
+ private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("\\{(\\w[-\\w]*)\\}");
+ private static SimpleDateFormat ISO8601_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ private static Pattern ISO8601_DATE_PATTERN = Pattern.compile(
+ "(\\d{4}-\\d{2}-\\d{2})[ T](\\d{2}:\\d{2}:\\d{2})(.\\d{3,})?([+-]\\d{2}:\\d{2}|[+-]\\d{4}|[+-]\\d{2}|Z)");
+
+ public static HttpMethod getPostMethodFromURL(final String requestUrl) {
+ int n = requestUrl.indexOf('?');
+ if (n == -1) {
+ return new PostMethod(requestUrl);
+ }
+ PostMethod postMethod = new PostMethod(requestUrl.substring(0, n));
+ String[] queryParams = requestUrl.substring(n + 1).split("&");
+ postMethod.addParameters(ContainerUtil.map2Array(queryParams, NameValuePair.class, new Function<String, NameValuePair>() {
+ @Override
+ public NameValuePair fun(String s) {
+ String[] nv = s.split("=");
+ if (nv.length == 1) {
+ return new NameValuePair(nv[0], "");
+ }
+ return new NameValuePair(nv[0], nv[1]);
+ }
+ }));
+ return postMethod;
+ }
+
+ public static String substituteTemplateVariables(String s, Collection<TemplateVariable> variables) {
+ Map<String, String> lookup = new HashMap<String, String>();
+ for (TemplateVariable v : variables) {
+ lookup.put(v.getName(), v.getValue());
+ }
+ StringBuffer sb = new StringBuffer();
+ Matcher m = PLACEHOLDER_PATTERN.matcher(s);
+ while (m.find()) {
+ String replacement = lookup.containsKey(m.group(1)) ? lookup.get(m.group(1)) : m.group(0);
+ m.appendReplacement(sb, replacement);
+ }
+ return m.appendTail(sb).toString();
+ }
+
+ public static List<String> createPlaceholdersList(GenericRepository repository) {
+ return createPlaceholdersList(repository.getAllTemplateVariables());
+ }
+
+ public static List<String> createPlaceholdersList(List<TemplateVariable> variables) {
+ return ContainerUtil.map2List(variables, new Function<TemplateVariable, String>() {
+ @Override
+ public String fun(TemplateVariable variable) {
+ return String.format("{%s}", variable.getName());
+ }
+ });
+ }
+
+ @Nullable
+ public static Date parseISO8601Date(@NotNull String s) {
+ // SimpleDateFormat prior JDK7 doesn't support 'X' specifier for ISO 8601 timezone format.
+ // Because some bug trackers and task servers e.g. send dates ending with 'Z' (that stands for UTC),
+ // dates should be preprocessed before parsing.
+ Matcher m = ISO8601_DATE_PATTERN.matcher(s);
+ if (!m.matches()) {
+ return null;
+ }
+ String datePart = m.group(1);
+ String timePart = m.group(2);
+ String milliseconds = m.group(3);
+ milliseconds = milliseconds == null? "000" : milliseconds.substring(1, 4);
+ String timezone = m.group(4);
+ if (timezone.equals("Z")) {
+ timezone = "+0000";
+ } else if (timezone.length() == 3) {
+ // [+-]HH
+ timezone += "00";
+ } else if (timezone.length() == 6) {
+ // [+-]HH:MM
+ timezone = timezone.substring(0, 3) + timezone.substring(4, 6);
+ }
+ String canonicalForm = String.format("%sT%s.%s%s", datePart, timePart, milliseconds, timezone);
+ try {
+ return ISO8601_DATE_FORMAT.parse(canonicalForm);
+ }
+ catch (ParseException e) {
+ return null;
+ }
+ }
+
+ public static String prettifyVariableName(String variableName) {
+ String prettyName = variableName.replace('_', ' ');
+ return StringUtil.capitalizeWords(prettyName, true);
+ }
+
+ public static <T> List<T> concat(List<? extends T> list, T... values) {
+ return ContainerUtil.concat(true, list, values);
+ }
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericTask.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericTask.java
index 0cca695..43234c2 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericTask.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericTask.java
@@ -12,12 +12,17 @@
public class GenericTask extends Task {
private final String myId;
- private final String myDescription;
+ private final String mySummary;
+ private String myDescription;
+ private Date myUpdated;
+ private Date myCreated;
+ private String myIssueUrl;
private TaskRepository myRepository;
+ private boolean myClosed;
- public GenericTask(final String id, final String description, final TaskRepository repository) {
+ public GenericTask(final String id, final String summary, final TaskRepository repository) {
myId = id;
- myDescription = description;
+ mySummary = summary;
myRepository = repository;
}
@@ -30,25 +35,25 @@
@NotNull
@Override
public String getSummary() {
- return myDescription;
+ return mySummary;
}
@Nullable
@Override
public String getDescription() {
- return null;
+ return myDescription;
}
@NotNull
@Override
public Comment[] getComments() {
- return new Comment[0];
+ return Comment.EMPTY_ARRAY;
}
@NotNull
@Override
public Icon getIcon() {
- return myRepository.getRepositoryType().getIcon();
+ return myRepository.getIcon();
}
@NotNull
@@ -60,18 +65,18 @@
@Nullable
@Override
public Date getUpdated() {
- return null;
+ return myUpdated;
}
@Nullable
@Override
public Date getCreated() {
- return null;
+ return myCreated;
}
@Override
public boolean isClosed() {
- return false;
+ return myClosed;
}
@Override
@@ -82,7 +87,7 @@
@Nullable
@Override
public String getIssueUrl() {
- return null;
+ return myIssueUrl;
}
@Nullable
@@ -90,4 +95,24 @@
public TaskRepository getRepository() {
return myRepository;
}
+
+ public void setIssueUrl(@Nullable String issueUrl) {
+ myIssueUrl = issueUrl;
+ }
+
+ public void setCreated(@Nullable Date created) {
+ myCreated = created;
+ }
+
+ public void setUpdated(@Nullable Date updated) {
+ myUpdated = updated;
+ }
+
+ public void setDescription(@Nullable String description) {
+ myDescription = description;
+ }
+
+ public void setClosed(boolean closed) {
+ myClosed = closed;
+ }
}
\ No newline at end of file
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/HighlightedSelectorsTable.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/HighlightedSelectorsTable.java
new file mode 100644
index 0000000..48d7b1b
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/HighlightedSelectorsTable.java
@@ -0,0 +1,99 @@
+/*
+ * 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.tasks.generic;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.ui.LanguageTextField;
+import com.intellij.ui.table.TableView;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.ColumnInfo;
+import com.intellij.util.ui.ListTableModel;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.table.TableCellRenderer;
+import java.awt.*;
+import java.util.List;
+
+
+class HighlightedSelectorsTable extends TableView<Selector> {
+
+ private final FileType myValueFileType;
+ private final Project myProject;
+
+ public HighlightedSelectorsTable(@NotNull FileType valueFileType, @NotNull Project project) {
+ this(valueFileType, project, ContainerUtil.<Selector>emptyList());
+ }
+
+ public HighlightedSelectorsTable(@NotNull final FileType valueFileType, @NotNull final Project project, @NotNull final List<Selector> selectors) {
+ super(new ListTableModel<Selector>(new ColumnInfo[]{
+ new ColumnInfo<Selector, String>("Name") {
+ @Nullable
+ @Override
+ public String valueOf(Selector selector) {
+ return selector.getName();
+ }
+ },
+ new ColumnInfo<Selector, String>("Path") {
+ @Nullable
+ @Override
+ public String valueOf(Selector selector) {
+ return selector.getPath();
+ }
+
+ @Override
+ public boolean isCellEditable(Selector selector) {
+ return true;
+ }
+
+ @Override
+ public void setValue(Selector selector, String value) {
+ selector.setPath(value);
+ }
+
+ @Nullable
+ @Override
+ public TableCellRenderer getRenderer(Selector selector) {
+ return new LanguageTextFieldRenderer(((LanguageFileType)valueFileType).getLanguage(), project);
+ }
+ }
+ }, selectors, 0));
+ myValueFileType = valueFileType;
+ myProject = project;
+ }
+ public List<Selector> getSelectors() {
+ return getItems();
+ }
+
+ private static class LanguageTextFieldRenderer implements TableCellRenderer {
+ private final Project myProject;
+ private final Language myLanguage;
+
+ private LanguageTextFieldRenderer(Language language, Project project) {
+ myProject = project;
+ myLanguage = language;
+ }
+
+ @Override
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ return new LanguageTextField(myLanguage, myProject, (String)value);
+ }
+ }
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java
new file mode 100644
index 0000000..e2f1ea8
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java
@@ -0,0 +1,162 @@
+package com.intellij.tasks.generic;
+
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.PlainTextFileType;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.tasks.Task;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.xmlb.annotations.Tag;
+import com.jayway.jsonpath.InvalidPathException;
+import com.jayway.jsonpath.JsonPath;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Author: Mikhail Golubev
+ */
+@Tag("JsonResponseHandler")
+public final class JsonPathResponseHandler extends SelectorBasedResponseHandler {
+
+ private static final Map<Class<?>, String> JSON_TYPES = ContainerUtil.newHashMap(
+ new Pair<Class<?>, String>(Map.class, "JSON object"),
+ new Pair<Class<?>, String>(List.class, "JSON array"),
+ new Pair<Class<?>, String>(String.class, "JSON string"),
+ new Pair<Class<?>, String>(Integer.class, "JSON number"),
+ new Pair<Class<?>, String>(Double.class, "JSON number"),
+ new Pair<Class<?>, String>(Boolean.class, "JSON boolean")
+ );
+
+ /**
+ * Serialization constructor
+ */
+ @SuppressWarnings("UnusedDeclaration")
+ public JsonPathResponseHandler() {
+ }
+
+ public JsonPathResponseHandler(GenericRepository repository) {
+ super(repository);
+ }
+
+ @Override
+ public FileType getSelectorFileType() {
+ return PlainTextFileType.INSTANCE;
+ }
+
+ @SuppressWarnings("unchecked")
+ @NotNull
+ @Override
+ public Task[] doParseIssues(String response) throws Exception {
+ Object tasksMatch = JsonPath.read(response, getSelectorPath("tasks"));
+ if (!(tasksMatch instanceof List)) {
+ throw new Exception("Selector 'task' should match array of tasks. Got " + tasksMatch.toString() + " instead");
+ }
+ List<Object> tasks = (List<Object>)tasksMatch;
+ List<GenericTask> result = new ArrayList<GenericTask>(tasks.size());
+ for (Object rawTask : tasks) {
+ String taskText = rawTask.toString();
+ String id = extractId(taskText, getSelector("id"));
+ String summary = extractString(taskText, getSelector("summary"));
+ assert summary != null;
+ GenericTask task = new GenericTask(id, summary, myRepository);
+ task.setDescription(extractString(response, getSelector("description")));
+ task.setIssueUrl(extractString(response, getSelector("issueUrl")));
+ Boolean closed = extractBoolean(response, getSelector("closed"));
+ if (closed != null) {
+ task.setClosed(closed);
+ }
+ task.setUpdated(extractDate(response, getSelector("updated")));
+ task.setCreated(extractDate(response, getSelector("created")));
+ result.add(task);
+ }
+ return result.toArray(new Task[result.size()]);
+ }
+
+ @Nullable
+ @Override
+ public Task doParseIssue(String response) throws Exception {
+ String id = extractId(response, getSelector("singleTask-id"));
+ String summary = extractString(response, getSelector("singleTask-summary"));
+ GenericTask task = new GenericTask(id, summary, myRepository);
+ task.setDescription(extractString(response, getSelector("singleTask-description")));
+ task.setIssueUrl(extractString(response, getSelector("singleTask-issueUrl")));
+ Boolean closed = extractBoolean(response, getSelector("singleTask-closed"));
+ if (closed != null) {
+ task.setClosed(closed);
+ }
+ task.setUpdated(extractDate(response, getSelector("singleTask-updated")));
+ task.setCreated(extractDate(response, getSelector("singleTask-created")));
+ return task;
+ }
+
+ @SuppressWarnings({"unchecked", "MethodMayBeStatic"})
+ @Nullable
+ private <T> T extractValueAndCheckType(String source, Selector selector, Class<T> cls) throws Exception {
+ if (selector == null || StringUtil.isEmpty(selector.getPath())) {
+ return null;
+ }
+ Object value;
+ try {
+ value = JsonPath.read(source, selector.getPath());
+ }
+ catch (InvalidPathException e) {
+ // NOTE: could be thrown when selector is actually invalid or just not matched
+ throw new Exception(String.format("JsonPath expression '%s' is malformed or didn't match", selector.getPath()), e);
+ }
+ if (value == null) {
+ return null;
+ }
+ if (!(cls.isInstance(value))) {
+ throw new Exception(
+ String.format("Selector '%s' should match %s. Got '%s' instead", selector.getName(), JSON_TYPES.get(cls), value.toString()));
+ }
+ return (T)value;
+ }
+
+ @SuppressWarnings("MethodMayBeStatic")
+ @Nullable
+ private String extractId(String task, Selector idSelector) throws Exception {
+ Object rawId;
+ try {
+ rawId = JsonPath.read(task, idSelector.getPath());
+ }
+ catch (InvalidPathException e) {
+ throw new Exception(String.format("JsonPath expression '%s' is malformed or didn't match", idSelector.getPath()), e);
+ }
+ if (!(rawId instanceof String) && !(rawId instanceof Long)) {
+ throw new Exception(
+ String.format("Selector 'id' should match either JSON string or JSON number value. Got '%s' instead", rawId.toString()));
+ }
+ return String.valueOf(rawId);
+ }
+
+ private String extractString(String source, Selector selector) throws Exception {
+ return extractValueAndCheckType(source, selector, String.class);
+ }
+
+ private Boolean extractBoolean(String source, Selector selector) throws Exception {
+ return extractValueAndCheckType(source, selector, Boolean.class);
+ }
+
+ private Long extractLong(String source, Selector selector) throws Exception {
+ return extractValueAndCheckType(source, selector, Long.class);
+ }
+
+ private Date extractDate(String response, Selector selector) throws Exception {
+ String dateString = extractString(response, selector);
+ if (dateString == null) {
+ return null;
+ }
+ return GenericRepositoryUtil.parseISO8601Date(dateString);
+ }
+
+ @Override
+ public ResponseType getResponseType() {
+ return ResponseType.JSON;
+ }
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java
index a783b66..fca6b21 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java
@@ -8,6 +8,7 @@
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.util.List;
@@ -88,6 +89,24 @@
setModified();
}
+ @Override
+ public TableCellRenderer getRenderer(TemplateVariable variable) {
+ if (variable.getIsHidden()) {
+ return new TableCellRenderer() {
+ @Override
+ public Component getTableCellRendererComponent(JTable table,
+ Object value,
+ boolean isSelected,
+ boolean hasFocus,
+ int row,
+ int column) {
+ return new JPasswordField(value.toString());
+ }
+ };
+ }
+ return super.getRenderer(variable);
+ }
+
@Nullable
@Override
protected String getDescription(TemplateVariable templateVariable) {
@@ -95,7 +114,68 @@
}
};
- return new ListTableModel((new ColumnInfo[]{name, value}));
+ final ColumnInfo isShownOnFirstTab = new ColumnInfo<TemplateVariable, Boolean>("Show on first tab") {
+ @Nullable
+ @Override
+ public Boolean valueOf(TemplateVariable o) {
+ return o.getIsShownOnFirstTab();
+ }
+
+ @Override
+ public void setValue(TemplateVariable variable, Boolean value) {
+ variable.setIsShownOnFirstTab(value);
+ setModified();
+ }
+
+ @Override
+ public Class getColumnClass() {
+ return Boolean.class;
+ }
+
+ @Override
+ public boolean isCellEditable(TemplateVariable variable) {
+ return !variable.getIsPredefined();
+ }
+
+ @Nullable
+ @Override
+ public String getTooltipText() {
+ return "Whether this template variable will be shown in 'General tab'";
+ }
+ };
+
+ final ColumnInfo isHidden = new ColumnInfo<TemplateVariable, Boolean>("Hide") {
+ @Nullable
+ @Override
+ public Boolean valueOf(TemplateVariable o) {
+ return o.getIsHidden();
+ }
+
+ @Override
+ public void setValue(TemplateVariable variable, Boolean value) {
+ variable.setIsHidden(value);
+ setModified();
+ // value column editor may be changed
+ TemplateVariablesTable.this.refreshValues();
+ }
+
+ @Override
+ public Class getColumnClass() {
+ return Boolean.class;
+ }
+
+ @Override
+ public boolean isCellEditable(TemplateVariable variable) {
+ return !variable.getIsPredefined();
+ }
+
+ @Nullable
+ @Override
+ public String getTooltipText() {
+ return "Whether this template variable will be hidden like password field";
+ }
+ };
+ return new ListTableModel((new ColumnInfo[]{name, value, isShownOnFirstTab, isHidden}));
}
@Override
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java
new file mode 100644
index 0000000..45332b5d
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java
@@ -0,0 +1,164 @@
+package com.intellij.tasks.generic;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.event.DocumentAdapter;
+import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.XmlElementFactory;
+import com.intellij.psi.xml.XmlTag;
+import com.intellij.tasks.Task;
+import com.intellij.ui.EditorTextField;
+import com.intellij.ui.LanguageTextField;
+import com.intellij.ui.components.JBScrollPane;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.FormBuilder;
+import com.intellij.util.xmlb.annotations.Tag;
+import com.intellij.xml.util.XmlUtil;
+import org.intellij.lang.regexp.RegExpLanguage;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Handler that uses legacy regex-based approach for tasks extraction.
+ *
+ * @author Evgeny.Zakrevsky
+ * @author Mikhail Golubev
+ */
+@Tag("RegExResponseHandler")
+public final class RegExResponseHandler extends ResponseHandler {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.tasks.generic.RegExResponseHandler");
+ private static final String ID_PLACEHOLDER = "{id}";
+ private static final String SUMMARY_PLACEHOLDER = "{summary}";
+
+ private String myTaskRegex = "";
+
+ /**
+ * Serialization constructor
+ */
+ @SuppressWarnings("UnusedDeclaration")
+ public RegExResponseHandler() {
+ // empty
+ }
+
+ public RegExResponseHandler(GenericRepository repository) {
+ super(repository);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ RegExResponseHandler handler = (RegExResponseHandler)o;
+ return myTaskRegex.equals(handler.myTaskRegex);
+ }
+
+ @Override
+ public int hashCode() {
+ return myTaskRegex.hashCode();
+ }
+
+ @Override
+ public JComponent getConfigurationComponent(Project project) {
+ FormBuilder builder = FormBuilder.createFormBuilder();
+ final EditorTextField taskPatternText;
+ taskPatternText = new LanguageTextField(RegExpLanguage.INSTANCE, project, myTaskRegex, false);
+ taskPatternText.addDocumentListener(new DocumentAdapter() {
+ @Override
+ public void documentChanged(DocumentEvent e) {
+ myTaskRegex = taskPatternText.getText();
+ }
+ });
+ String tooltip = "<html>Task pattern should be a regexp with two matching groups: ({id}.+?) and ({summary}.+?)";
+ builder.addLabeledComponent("Task Pattern:", new JBScrollPane(taskPatternText)).addTooltip(tooltip);
+ return builder.getPanel();
+ }
+
+ @NotNull
+ @Override
+ public Task[] parseIssues(String response) throws Exception {
+ final List<String> placeholders = getPlaceholders(myTaskRegex);
+ if (!placeholders.contains(ID_PLACEHOLDER) || !placeholders.contains(SUMMARY_PLACEHOLDER)) {
+ throw new Exception("Incorrect Task Pattern");
+ }
+
+ final String taskPatternWithoutPlaceholders = myTaskRegex.replaceAll("\\{.+?\\}", "");
+ Matcher matcher = Pattern
+ .compile(taskPatternWithoutPlaceholders,
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL | Pattern.UNICODE_CASE | Pattern.CANON_EQ)
+ .matcher(response);
+
+ List<Task> tasks = new ArrayList<Task>();
+ while (matcher.find()) {
+ String id = matcher.group(placeholders.indexOf(ID_PLACEHOLDER) + 1);
+ String summary = matcher.group(placeholders.indexOf(SUMMARY_PLACEHOLDER) + 1);
+ // temporary workaround to make AssemblaIntegrationTestPass
+ final String finalSummary = summary;
+ summary = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ @Override
+ public String compute() {
+ XmlElementFactory factory = XmlElementFactory.getInstance(ProjectManager.getInstance().getDefaultProject());
+ XmlTag text = factory.createTagFromText("<a>" + finalSummary + "</a>");
+ String trimmedText = text.getValue().getTrimmedText();
+ return XmlUtil.decode(trimmedText);
+ }
+ });
+ tasks.add(new GenericTask(id, summary, myRepository));
+ }
+ return tasks.toArray(new Task[tasks.size()]);
+ }
+
+ @Nullable
+ @Override
+ public Task parseIssue(String response) throws Exception {
+ return null;
+ }
+
+ private static List<String> getPlaceholders(String value) {
+ if (value == null) {
+ return ContainerUtil.emptyList();
+ }
+
+ List<String> vars = new ArrayList<String>();
+ Matcher m = Pattern.compile("\\{(.+?)\\}").matcher(value);
+ while (m.find()) {
+ vars.add(m.group(0));
+ }
+ return vars;
+ }
+
+ public String getTaskRegex() {
+ return myTaskRegex;
+ }
+
+ public void setTaskRegex(String taskRegex) {
+ myTaskRegex = taskRegex;
+ }
+
+ @Override
+ public boolean isConfigured() {
+ return !StringUtil.isEmpty(myTaskRegex);
+ }
+
+ @Override
+ public ResponseType getResponseType() {
+ return ResponseType.TEXT;
+ }
+
+ @Override
+ public RegExResponseHandler clone() {
+ RegExResponseHandler clone = (RegExResponseHandler)super.clone();
+ clone.myTaskRegex = myTaskRegex;
+ return clone;
+ }
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java
new file mode 100644
index 0000000..94bdd97
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java
@@ -0,0 +1,63 @@
+package com.intellij.tasks.generic;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.tasks.Task;
+import com.intellij.util.xmlb.annotations.Transient;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * ResponseHandler subclasses represent different strategies of extracting tasks from
+ * task server responses (e.g. using regular expressions, XPath, JSONPath, CSS selector etc.).
+ *
+ * @see XPathResponseHandler
+ * @see JsonPathResponseHandler
+ * @see RegExResponseHandler
+ * @author Mikhail Golubev
+ */
+public abstract class ResponseHandler implements Cloneable {
+
+ // XXX: what about serialization of circular dependencies?
+ protected GenericRepository myRepository;
+
+ // Serialization constructor
+ public ResponseHandler() {
+ // empty
+ }
+
+ public ResponseHandler(GenericRepository repository) {
+ myRepository = repository;
+ }
+
+ public void setRepository(GenericRepository repository) {
+ myRepository = repository;
+ }
+
+ @Transient
+ public GenericRepository getRepository() {
+ return myRepository;
+ }
+
+ public abstract JComponent getConfigurationComponent(Project project);
+
+ public abstract ResponseType getResponseType();
+
+ @NotNull
+ public abstract Task[] parseIssues(String response) throws Exception;
+
+ @Nullable
+ public abstract Task parseIssue(String response) throws Exception;
+
+ public abstract boolean isConfigured();
+
+ @Override
+ public ResponseHandler clone() {
+ try {
+ return (ResponseHandler) super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new AssertionError("ResponseHandler#clone() should be supported");
+ }
+ }
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseType.java
index 6a1248d..aa4bd78 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseType.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseType.java
@@ -4,29 +4,39 @@
import com.intellij.ide.highlighter.XmlFileType;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.PlainTextFileType;
+import org.intellij.lang.regexp.RegExpFileType;
+import org.intellij.lang.xpath.XPathFileType;
/**
* User: evgeny.zakrevsky
* Date: 10/25/12
*/
public enum ResponseType {
- XML("application/xml", XmlFileType.INSTANCE),
- HTML("text/html", HtmlFileType.INSTANCE),
- JSON("application/json", PlainTextFileType.INSTANCE);
+ XML("application/xml", XmlFileType.INSTANCE, XPathFileType.XPATH2),
+ JSON("application/json", PlainTextFileType.INSTANCE, PlainTextFileType.INSTANCE),
+ // TODO: think about possible selector type if it needed at all (e.g. CSS selector)
+ HTML("text/html", HtmlFileType.INSTANCE, PlainTextFileType.INSTANCE),
+ TEXT("text/plain", PlainTextFileType.INSTANCE, RegExpFileType.INSTANCE);
private String myMimeType;
- private FileType myFileType;
+ private FileType myContentFileType;
+ private FileType mySelectorFileType;
- ResponseType(final String s, final FileType fileType) {
+ ResponseType(final String s, final FileType contentFileType, final FileType selectorFileType) {
myMimeType = s;
- myFileType = fileType;
+ myContentFileType = contentFileType;
+ mySelectorFileType = selectorFileType;
}
public String getMimeType() {
return myMimeType;
}
- public FileType getFileType() {
- return myFileType;
+ public FileType getContentFileType() {
+ return myContentFileType;
+ }
+
+ public FileType getSelectorFileType() {
+ return mySelectorFileType;
}
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/Selector.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/Selector.java
new file mode 100644
index 0000000..ea30e2f
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/Selector.java
@@ -0,0 +1,87 @@
+package com.intellij.tasks.generic;
+
+import com.intellij.util.xmlb.annotations.Attribute;
+import com.intellij.util.xmlb.annotations.Tag;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Mikhail Golubev
+ */
+
+@Tag("selector")
+public final class Selector {
+ @NotNull private String myName;
+ @NotNull private String myPath;
+
+
+ /**
+ * Serialization constructor
+ */
+ @SuppressWarnings({"UnusedDeclatation"})
+ public Selector() {
+ // empty
+ }
+
+ public Selector(@NotNull String name) {
+ this(name, "");
+ }
+
+ public Selector(@NotNull String name, @NotNull String path) {
+ myName = name;
+ myPath = path;
+ }
+
+ public Selector(Selector other) {
+ myName = other.myName;
+ myPath = other.myPath;
+ }
+
+ @Attribute("name")
+ @NotNull
+ public String getName() {
+ return myName;
+ }
+
+ @Attribute("path")
+ @NotNull
+ public String getPath() {
+ return myPath;
+ }
+
+ public void setName(@NotNull String name) {
+ myName = name;
+ }
+
+ public void setPath(@NotNull String path) {
+ myPath = path;
+ }
+
+ public Selector clone() {
+ return new Selector(this);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Selector(name='%s', path='%s')", getName(), getPath());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Selector selector = (Selector)o;
+
+ if (!myName.equals(selector.myName)) return false;
+ if (!myPath.equals(selector.myPath)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = myName.hashCode();
+ result = (31 * result) + (myPath.hashCode());
+ return result;
+ }
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java
new file mode 100644
index 0000000..5ef8809
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java
@@ -0,0 +1,158 @@
+package com.intellij.tasks.generic;
+
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.tasks.Task;
+import com.intellij.ui.components.JBScrollPane;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.xmlb.annotations.AbstractCollection;
+import com.intellij.util.xmlb.annotations.Property;
+import com.intellij.util.xmlb.annotations.Tag;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+/**
+ * @author Mikhail Golubev
+ */
+public abstract class SelectorBasedResponseHandler extends ResponseHandler {
+
+ protected LinkedHashMap<String, Selector> mySelectors = new LinkedHashMap<String, Selector>();
+
+ /**
+ * Serialization constructor
+ */
+ @SuppressWarnings("UnusedDeclaration")
+ protected SelectorBasedResponseHandler() {
+ // empty
+ }
+
+ protected SelectorBasedResponseHandler(GenericRepository repository) {
+ super(repository);
+ // standard selectors
+ setSelectors(ContainerUtil.newArrayList(
+ // matched against list of tasks at whole downloaded from "taskListUrl"
+ new Selector("tasks", ""),
+
+ // matched against single tasks extracted from the list downloaded from "taskListUrl"
+ new Selector("id"),
+ new Selector("summary"),
+ new Selector("description"),
+ new Selector("updated"),
+ new Selector("created"),
+ new Selector("closed"),
+ new Selector("issueUrl"),
+
+ // matched against single task downloaded from "singleTaskUrl"
+ new Selector("singleTask-id"),
+ new Selector("singleTask-summary"),
+ new Selector("singleTask-description"),
+ new Selector("singleTask-updated"),
+ new Selector("singleTask-created"),
+ new Selector("singleTask-closed"),
+ new Selector("singleTask-issueUrl")
+ ));
+ }
+
+ public abstract FileType getSelectorFileType();
+
+ @Tag("selectors")
+ @Property(surroundWithTag = false)
+ @AbstractCollection(surroundWithTag = false)
+ @NotNull
+ public List<Selector> getSelectors() {
+ return new ArrayList<Selector>(mySelectors.values());
+ }
+
+ public void setSelectors(@NotNull List<Selector> selectors) {
+ mySelectors.clear();
+ for (Selector selector : selectors) {
+ mySelectors.put(selector.getName(), selector);
+ }
+ }
+
+ @Nullable
+ public Selector getSelector(@NotNull String name) {
+ return mySelectors.get(name);
+ }
+
+ @Nullable
+ public String getSelectorPath(@NotNull String name) {
+ Selector s = getSelector(name);
+ return s == null ? null : s.getPath();
+ }
+
+ @Override
+ public JComponent getConfigurationComponent(Project project) {
+ HighlightedSelectorsTable table = new HighlightedSelectorsTable(getSelectorFileType(),
+ project,
+ getSelectors());
+ return new JBScrollPane(table);
+ }
+
+ @Override
+ public SelectorBasedResponseHandler clone() {
+ SelectorBasedResponseHandler clone = (SelectorBasedResponseHandler)super.clone();
+ clone.mySelectors = new LinkedHashMap<String, Selector>(mySelectors.size());
+ for (Selector selector : mySelectors.values()) {
+ clone.mySelectors.put(selector.getName(), selector.clone());
+ }
+ return clone;
+ }
+
+ @Override
+ public boolean isConfigured() {
+ Selector idSelector = getSelector("id");
+ if (idSelector == null || StringUtil.isEmpty(idSelector.getPath())) return false;
+ Selector summarySelector = getSelector("summary");
+ if (summarySelector == null || StringUtil.isEmpty(summarySelector.getPath())) return false;
+ return true;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SelectorBasedResponseHandler)) return false;
+
+ SelectorBasedResponseHandler handler = (SelectorBasedResponseHandler)o;
+
+ if (!mySelectors.equals(handler.mySelectors)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return mySelectors.hashCode();
+ }
+
+ @NotNull
+ @Override
+ public final Task[] parseIssues(String response) throws Exception {
+ if (StringUtil.isEmpty(getSelectorPath("tasks")) ||
+ StringUtil.isEmpty(getSelectorPath("id")) ||
+ StringUtil.isEmpty(getSelectorPath("summary"))) {
+ throw new Exception("Selectors 'tasks', 'id' and 'summary' are mandatory");
+ }
+ return doParseIssues(response);
+ }
+
+ protected abstract Task[] doParseIssues(String response) throws Exception;
+
+ @Nullable
+ @Override
+ public final Task parseIssue(String response) throws Exception {
+ if (StringUtil.isEmpty(getSelectorPath("singleTask-id")) ||
+ StringUtil.isEmpty(getSelectorPath("singleTask-summary"))) {
+ throw new Exception("Selectors 'singleTask-id' and 'singleTask-summary' are mandatory");
+ }
+ return doParseIssue(response);
+ }
+
+ protected abstract Task doParseIssue(String response) throws Exception;
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/TemplateVariable.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/TemplateVariable.java
index e89fdd7..d8377bb 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/TemplateVariable.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/TemplateVariable.java
@@ -1,5 +1,6 @@
package com.intellij.tasks.generic;
+import com.intellij.util.xmlb.annotations.Attribute;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -10,17 +11,55 @@
*/
public class TemplateVariable {
private String myName;
- private String myValue;
- private boolean myIsPredefined;
+ private String myValue = "";
private String myDescription;
+ private boolean myIsPredefined;
+ private boolean myIsHidden;
+ private boolean myIsShownOnFirstTab;
- public TemplateVariable(@NotNull @NonNls String name, @NotNull @NonNls String value, boolean isPredefined, @Nullable String description) {
+ public static TemplateVariableBuilder builder(String name) {
+ return new TemplateVariableBuilder(name);
+ }
+
+ private TemplateVariable(TemplateVariableBuilder builder) {
+ myName = builder.myName;
+ myValue = builder.myValue;
+ myDescription = builder.myDescription;
+ myIsHidden = builder.myIsHidden;
+ myIsShownOnFirstTab = builder.myIsShowOnFirstTab;
+ myIsPredefined = builder.myIsPredefined;
+ }
+
+ public TemplateVariable(String name, Object value) {
+ this(name, value, false, "");
+ }
+
+ public TemplateVariable(@NotNull @NonNls String name, @NotNull @NonNls Object value, boolean isPredefined, @Nullable String description) {
myName = name;
- myValue = value;
+ myValue = String.valueOf(value);
myIsPredefined = isPredefined;
myDescription = description;
}
+ /**
+ * Serialization constructor
+ */
+ public TemplateVariable() {
+ }
+
+
+ /**
+ * Cloning constructor
+ */
+ private TemplateVariable(TemplateVariable other) {
+ myName = other.getName();
+ myValue = other.getValue();
+ myDescription = other.getDescription();
+ myIsHidden = other.getIsHidden();
+ myIsPredefined = other.getIsPredefined();
+ myIsShownOnFirstTab = other.getIsShownOnFirstTab();
+ }
+
public void setName(String name) {
myName = name;
}
@@ -42,15 +81,133 @@
return myDescription;
}
+ @Attribute("isPredefined")
public boolean getIsPredefined() {
return myIsPredefined;
}
+ public void setIsPredefined(boolean isPredefined) {
+ myIsPredefined = isPredefined;
+ }
+
+ @Attribute("isHidden")
+ public boolean getIsHidden() {
+ return myIsHidden;
+ }
+
+ public void setIsHidden(boolean isHidden) {
+ myIsHidden = isHidden;
+ }
+
+ @Attribute("shownOnFirstTab")
+ public boolean getIsShownOnFirstTab() {
+ return myIsShownOnFirstTab;
+ }
+
+ public void setIsShownOnFirstTab(boolean isShownOnFirstTab) {
+ myIsShownOnFirstTab = isShownOnFirstTab;
+ }
+
public TemplateVariable clone() {
- return new TemplateVariable(myName, myValue, myIsPredefined, myDescription);
+ return new TemplateVariable(this);
}
public void setDescription(final String description) {
myDescription = description;
}
+
+ @Override
+ public String toString() {
+ return String.format("TemplateVariable(name='%s', value='%s')", getName(), getValue());
+ }
+
+ public static class TemplateVariableBuilder {
+ private String myName;
+ private String myValue = "";
+ private String myDescription;
+ private boolean myIsHidden;
+ private boolean myIsPredefined;
+ private boolean myIsShowOnFirstTab;
+
+ private TemplateVariableBuilder(String name) {
+ myName = name;
+ }
+
+ public TemplateVariableBuilder value(Object value) {
+ myValue = String.valueOf(value);
+ return this;
+ }
+
+ public TemplateVariableBuilder description(String description) {
+ myDescription = description;
+ return this;
+ }
+
+ public TemplateVariableBuilder isHidden(boolean isHidden) {
+ myIsHidden = isHidden;
+ return this;
+ }
+
+ public TemplateVariableBuilder isPredefined(boolean isPredefined) {
+ myIsPredefined = isPredefined;
+ return this;
+ }
+
+ public TemplateVariableBuilder isShownOnFirstTab(boolean isShowOnFirstTab) {
+ myIsShowOnFirstTab = isShowOnFirstTab;
+ return this;
+ }
+
+ public TemplateVariable build() {
+ return new TemplateVariable(this);
+ }
+ }
+
+ /**
+ * Represents predefined template variable such as "serverUrl", "login" or "password" which are not
+ * set explicitly by user but instead taken from repository itself.
+ */
+ public abstract static class PredefinedFactoryVariable extends TemplateVariable {
+
+ protected PredefinedFactoryVariable(String name) {
+ this(name, false);
+ }
+
+ public PredefinedFactoryVariable(String name, boolean isHidden) {
+ this(name, name, isHidden);
+ }
+
+ public PredefinedFactoryVariable(String name, String description, boolean isHidden) {
+ super(builder(name).description(description).isHidden(isHidden));
+ }
+
+ @Override
+ public abstract String getValue();
+
+ @Override
+ public final void setName(String name) {
+ throw new UnsupportedOperationException("Name of predefined variable can't be changed");
+ }
+
+ @Override
+ public final void setValue(String value) {
+ throw new UnsupportedOperationException("Value of predefined variable can't be changed explicitly");
+ }
+
+ @Override
+ public final void setIsShownOnFirstTab(boolean isShownOnFirstTab) {
+ throw new UnsupportedOperationException("This parameter can't be changed for predefined variable");
+ }
+
+ @Override
+ public void setIsPredefined(boolean isPredefined) {
+ throw new UnsupportedOperationException("This parameter can't be changed for predefined variable");
+ }
+
+ @Override
+ public boolean getIsPredefined() {
+ return true;
+ }
+ }
+
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java
new file mode 100644
index 0000000..97dfc07
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java
@@ -0,0 +1,97 @@
+package com.intellij.tasks.generic;
+
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.tasks.Task;
+import com.intellij.util.xmlb.annotations.Tag;
+import org.intellij.lang.xpath.XPathFileType;
+import org.jetbrains.annotations.Nullable;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathFactory;
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+
+/**
+ * @author Mikhail Golubev
+ */
+@Tag("XPathResponseHandler")
+public final class XPathResponseHandler extends SelectorBasedResponseHandler {
+ private final static DocumentBuilder ourDocumentBuilder = createDocumentBuilder();
+ private static DocumentBuilder createDocumentBuilder() {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ try {
+ return factory.newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ throw new AssertionError("Can't create DocumentBuilder");
+ }
+ }
+
+ private final static XPathFactory ourXPathFactory = createXPathFactory();
+ private static XPathFactory createXPathFactory() {
+ return XPathFactory.newInstance();
+ }
+
+ /**
+ * Serialization constructor
+ */
+ @SuppressWarnings("UnusedDeclaration")
+ public XPathResponseHandler() {
+ // empty
+ }
+
+ public XPathResponseHandler(GenericRepository repository) {
+ super(repository);
+ }
+
+ @Override
+ public FileType getSelectorFileType() {
+ return XPathFileType.XPATH2;
+ }
+
+ @Override
+ public Task[] doParseIssues(String response) throws Exception {
+ String idSelector = getSelectorPath("id"), summarySelector = getSelectorPath("summary");
+ if (idSelector == null || summarySelector == null) {
+ throw new IllegalArgumentException("Selectors 'task', 'id' and 'summary' are mandatory");
+ }
+
+ Document document = ourDocumentBuilder.parse(new ByteArrayInputStream(response.getBytes()));
+
+ XPathExpression idPath = ourXPathFactory.newXPath().compile(idSelector);
+ NodeList idNodes = (NodeList)idPath.evaluate(document, XPathConstants.NODESET);
+
+ XPathExpression summaryPath = ourXPathFactory.newXPath().compile(summarySelector);
+ NodeList summaryNodes = (NodeList)summaryPath.evaluate(document, XPathConstants.NODESET);
+
+ if (summaryNodes.getLength() != idNodes.getLength()) {
+ // popup will be shown to the user
+ throw new IllegalArgumentException("Number of tasks selected by 'id' and 'summary' XPath expressions is not the same.");
+ }
+
+ ArrayList<Task> tasks = new ArrayList<Task>(idNodes.getLength());
+ for (int i = 0; i < idNodes.getLength(); i++) {
+ String id = idNodes.item(i).getNodeValue();
+ String summary = summaryNodes.item(i).getNodeValue();
+ tasks.add(new GenericTask(id, summary, myRepository));
+ }
+ return tasks.toArray(new Task[tasks.size()]);
+ }
+
+ @Nullable
+ @Override
+ public Task doParseIssue(String response) throws Exception {
+ return null;
+ }
+
+ @Override
+ public ResponseType getResponseType() {
+ return ResponseType.XML;
+ }
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/assembla/AssemblaRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/assembla/AssemblaRepository.java
index dfe20bf8..1356f9d 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/assembla/AssemblaRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/assembla/AssemblaRepository.java
@@ -2,31 +2,31 @@
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.tasks.TaskRepositoryType;
-import com.intellij.tasks.generic.GenericRepository;
-import com.intellij.tasks.generic.GenericRepositoryEditor;
-import com.intellij.tasks.generic.ResponseType;
-import com.intellij.tasks.generic.TemplateVariable;
+import com.intellij.tasks.generic.*;
import com.intellij.util.xmlb.annotations.Tag;
-import java.util.List;
-
/**
* User: evgeny.zakrevsky
* Date: 10/26/12
*/
+// TODO: move to new Generic Repository API
@Tag("Assembla")
public class AssemblaRepository extends GenericRepository {
+ private static final String TASK_REGEX =
+ "<ticket>.*?<number type=\"integer\">({id}.*?)</number>.*?<summary>({summary}.*?)</summary>.*?</ticket>";
+
@SuppressWarnings({"UnusedDeclaration"})
public AssemblaRepository() {
}
public AssemblaRepository(final TaskRepositoryType type) {
super(type);
- myUseHttpAuthentication = true;
+ setUseHttpAuthentication(true);
+ setUrl("http://www.assembla.com/");
}
- public AssemblaRepository(final GenericRepository other) {
+ public AssemblaRepository(final AssemblaRepository other) {
super(other);
}
@@ -36,38 +36,10 @@
}
@Override
- protected List<TemplateVariable> getTemplateVariablesDefault() {
- return super.getTemplateVariablesDefault();
- }
-
- @Override
- protected ResponseType getResponseTypeDefault() {
- return ResponseType.XML;
- }
-
- @Override
- protected String getTasksListMethodTypeDefault() {
- return GenericRepositoryEditor.GET;
- }
-
- @Override
- protected String getLoginMethodTypeDefault() {
- return GenericRepositoryEditor.POST;
- }
-
- @Override
- protected String getLoginURLDefault() {
- return "";
- }
-
- @Override
- protected String getTaskPatternDefault() {
- return "<ticket>.*?<number type=\"integer\">({id}.*?)</number>.*?<summary>({summary}.*?)</summary>.*?</ticket>";
- }
-
- @Override
- protected String getTasksListURLDefault() {
- return "http://www.assembla.com/tickets.xml";
+ public void resetToDefaults() {
+ super.resetToDefaults();
+ setTasksListUrl("http://www.assembla.com/tickets.xml");
+ setResponseType(ResponseType.TEXT);
}
@Override
@@ -84,4 +56,11 @@
protected int getFeatures() {
return BASIC_HTTP_AUTHORIZATION;
}
+
+ @Override
+ public ResponseHandler getTextResponseHandlerDefault() {
+ RegExResponseHandler regexHandler = new RegExResponseHandler(this);
+ regexHandler.setTaskRegex(TASK_REGEX);
+ return regexHandler;
+ }
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml
new file mode 100644
index 0000000..b374b7f
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml
@@ -0,0 +1,67 @@
+<Generic shared="false" url="https://app.asana.com/api/1.0">
+ <commitMessageFormat>{id} {summary}</commitMessageFormat>
+ <password/>
+ <option name="loginAnonymously" value="false"/>
+ <option name="loginMethodType" value="GET"/>
+ <option name="loginUrl" value=""/>
+ <option name="responseHandlers">
+ <XPathResponseHandler>
+ <selectors>
+ <selector name="tasks" path="foo"/>
+ <selector name="id" path=""/>
+ <selector name="summary" path=""/>
+ <selector name="description" path=""/>
+ <selector name="updated" path=""/>
+ <selector name="created" path=""/>
+ <selector name="issueUrl" path=""/>
+ <selector name="singleTask-id" path=""/>
+ <selector name="singleTask-summary" path=""/>
+ <selector name="singleTask-description" path=""/>
+ <selector name="singleTask-updated" path=""/>
+ <selector name="singleTask-created" path=""/>
+ <selector name="singleTask-issueUrl" path=""/>
+ </selectors>
+ </XPathResponseHandler>
+ <JsonResponseHandler>
+ <selectors>
+ <selector name="tasks" path="data[*]"/>
+ <selector name="id" path="id"/>
+ <selector name="summary" path="name"/>
+ <selector name="description" path=""/>
+ <selector name="updated" path=""/>
+ <selector name="created" path=""/>
+ <selector name="completed" path=""/>
+ <selector name="issueUrl" path=""/>
+ <selector name="singleTask-id" path="data.id"/>
+ <selector name="singleTask-summary" path="data.name"/>
+ <selector name="singleTask-description" path="data.notes"/>
+ <selector name="singleTask-updated" path="data.modified_at"/>
+ <selector name="singleTask-created" path="data.created_at"/>
+ <selector name="singleTask-closed" path="data.completed"/>
+ <selector name="singleTask-issueUrl" path=""/>
+ </selectors>
+ </JsonResponseHandler>
+ <RegExResponseHandler>
+ <option name="taskRegex" value=""/>
+ </RegExResponseHandler>
+ </option>
+ <option name="responseType" value="JSON"/>
+ <option name="shouldFormatCommitMessage" value="false"/>
+ <option name="singleTaskMethodType" value="GET"/>
+ <option name="singleTaskUrl" value="{serverUrl}/tasks/{id}"/>
+ <option name="subtypeName"/>
+ <option name="tasksListMethodType" value="GET"/>
+ <option name="tasksListUrl" value="{serverUrl}/projects/{project_ID}/tasks?assignee=me"/>
+ <option name="templateVariables">
+ <list>
+ <TemplateVariable isHidden="false" isPredefined="false" shownOnFirstTab="true">
+ <option name="description"/>
+ <option name="name" value="project_ID"/>
+ <option name="value" value=""/>
+ </TemplateVariable>
+ </list>
+ </option>
+ <option name="useHttpAuthentication" value="true"/>
+ <option name="useProxy" value="false"/>
+ <username/>
+</Generic>
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java
index 8c4785e..fb2c776 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskManagerImpl.java
@@ -36,6 +36,7 @@
import com.intellij.openapi.vcs.VcsType;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.tasks.*;
+import com.intellij.tasks.actions.TaskSearchSupport;
import com.intellij.tasks.config.TaskRepositoriesConfigurable;
import com.intellij.tasks.context.WorkingContextManager;
import com.intellij.ui.ColoredTreeCellRenderer;
@@ -571,6 +572,7 @@
}
catch (XmlSerializationException e) {
// ignore
+ LOG.error(e.getMessage());
}
}
}
@@ -766,10 +768,15 @@
continue;
}
try {
- final Task[] tasks = repository.getIssues(request, max, since, cancelled);
+ Task[] tasks = repository.getIssues(request, max, since, cancelled);
myBadRepositories.remove(repository);
if (issues == null) issues = new ArrayList<Task>(tasks.length);
- ContainerUtil.addAll(issues, tasks);
+ if (!repository.isSupported(TaskRepository.NATIVE_SEARCH)) {
+ List<Task> filteredTasks = TaskSearchSupport.filterTasks(request, ContainerUtil.list(tasks));
+ ContainerUtil.addAll(issues, filteredTasks);
+ } else {
+ ContainerUtil.addAll(issues, tasks);
+ }
}
catch (ProcessCanceledException ignored) {
// OK
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java
index 8a9fd91..63b1ca9 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java
@@ -118,7 +118,7 @@
@Override
protected int getFeatures() {
- return TIME_MANAGEMENT;
+ return super.getFeatures() | TIME_MANAGEMENT;
}
public String getSearchQuery() {
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java
index baefe2d..484a357bc 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java
@@ -1,6 +1,7 @@
package com.intellij.tasks.jira.jql.codeinsight;
import com.intellij.codeInsight.completion.*;
+import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Condition;
@@ -78,16 +79,16 @@
// Patterns:
- public static final PsiElementPattern.Capture<PsiElement> AFTER_CLAUSE_WITH_HISTORY_PREDICATE =
+ private static final PsiElementPattern.Capture<PsiElement> AFTER_CLAUSE_WITH_HISTORY_PREDICATE =
psiElement().and(rightAfterElement(JqlClauseWithHistoryPredicates.class));
private static final PsiElementPattern.Capture<PsiElement> AFTER_ANY_CLAUSE =
psiElement().and(rightAfterElement(JqlTerminalClause.class));
- public static final PsiElementPattern.Capture<PsiElement> AFTER_ORDER_KEYWORD =
+ private static final PsiElementPattern.Capture<PsiElement> AFTER_ORDER_KEYWORD =
psiElement().afterLeaf(psiElement(JqlTokenTypes.ORDER_KEYWORD));
- public static final PsiElementPattern.Capture<PsiElement> AFTER_FIELD_IN_CLAUSE =
+ private static final PsiElementPattern.Capture<PsiElement> AFTER_FIELD_IN_CLAUSE =
psiElement().and(rightAfterElement(
psiElement(JqlIdentifier.class).
andNot(psiElement().inside(JqlFunctionCall.class)).
@@ -103,6 +104,8 @@
psiElement().withElementType(JqlTokenTypes.AND_OPERATORS),
psiElement().withElementType(JqlTokenTypes.OR_OPERATORS),
psiElement().withElementType(JqlTokenTypes.NOT_OPERATORS).
+ andNot(psiElement().inside(JqlTerminalClause.class)),
+ psiElement().withElementType(JqlTokenTypes.LPAR).
andNot(psiElement().inside(JqlTerminalClause.class))
)));
@@ -259,8 +262,9 @@
@NotNull CompletionResultSet result) {
JqlFieldType operandType;
boolean listFunctionExpected;
- PsiElement pos = parameters.getPosition();
- JqlHistoryPredicate predicate = PsiTreeUtil.getParentOfType(pos, JqlHistoryPredicate.class);
+ PsiElement curElem = parameters.getPosition();
+ PsiElement origElem = parameters.getOriginalPosition();
+ JqlHistoryPredicate predicate = PsiTreeUtil.getParentOfType(curElem, JqlHistoryPredicate.class);
if (predicate != null) {
listFunctionExpected = false;
JqlHistoryPredicate.Type predicateType = predicate.getType();
@@ -276,15 +280,16 @@
break;
// from, to
default:
- operandType = findTypeOfField(pos);
+ operandType = findTypeOfField(curElem);
}
}
else {
- operandType = findTypeOfField(pos);
- listFunctionExpected = insideClauseWithListOperator(pos);
+ operandType = findTypeOfField(curElem);
+ listFunctionExpected = insideClauseWithListOperator(curElem);
}
for (String functionName : JqlStandardFunction.allOfType(operandType, listFunctionExpected)) {
- result.addElement(LookupElementBuilder.create(functionName + "()"));
+ result.addElement(LookupElementBuilder.create(functionName)
+ .withInsertHandler(ParenthesesInsertHandler.NO_PARAMETERS));
}
}
@@ -301,15 +306,7 @@
if (clause == null || clause.getType() == null) {
return false;
}
- switch (clause.getType()) {
- case IN:
- case NOT_IN:
- case WAS_IN:
- case WAS_NOT_IN:
- return true;
- default:
- return false;
- }
+ return clause.getType().isListOperator();
}
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlStandardField.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlStandardField.java
index e6b0f96..366d56b 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlStandardField.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlStandardField.java
@@ -5,6 +5,7 @@
import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.MultiMap;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -64,7 +65,7 @@
private final String myName;
private final JqlFieldType myType;
- private JqlStandardField(String name, JqlFieldType type) {
+ JqlStandardField(String name, JqlFieldType type) {
myName = name;
myType = type;
}
@@ -100,10 +101,10 @@
}
public static Collection<String> allOfType(JqlFieldType type) {
- return type == JqlFieldType.UNKNOWN? ALL_FIELDS_NAMES : TYPE_LOOKUP.get(type);
+ return type == JqlFieldType.UNKNOWN? ALL_FIELD_NAMES : new ArrayList<String>(TYPE_LOOKUP.get(type));
}
- public static final List<String> ALL_FIELDS_NAMES = ContainerUtil.map2List(VALUES, new Function<JqlStandardField, String>() {
+ public static final List<String> ALL_FIELD_NAMES = ContainerUtil.map2List(VALUES, new Function<JqlStandardField, String>() {
@Override
public String fun(JqlStandardField field) {
return field.myName;
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlStandardFunction.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlStandardFunction.java
index 27f7c6c..8e6cf34 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlStandardFunction.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlStandardFunction.java
@@ -5,10 +5,9 @@
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.NotNull;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
/**
* @author Mikhail Golubev
@@ -71,7 +70,7 @@
}
});
- public static JqlStandardFunction byName(String name) {
+ public static JqlStandardFunction byName(@NotNull String name) {
return NAME_LOOKUP.get(name);
}
@@ -82,8 +81,11 @@
}
}
- public static Collection<String> allOfType(JqlFieldType type, boolean multipleResults) {
- return type == JqlFieldType.UNKNOWN? ALL_FUNCTION_NAMES : TYPE_LOOKUP.get(Pair.create(type, multipleResults));
+ public static List<String> allOfType(@NotNull JqlFieldType type, boolean multipleResults) {
+ if (type == JqlFieldType.UNKNOWN) {
+ return ALL_FUNCTION_NAMES;
+ }
+ return new ArrayList<String>(TYPE_LOOKUP.get(Pair.create(type, multipleResults)));
}
public static final List<String> ALL_FUNCTION_NAMES = ContainerUtil.map2List(VALUES, new Function<JqlStandardFunction, String>() {
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlTerminalClause.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlTerminalClause.java
index c087181..d16a106 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlTerminalClause.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlTerminalClause.java
@@ -12,25 +12,32 @@
*/
public interface JqlTerminalClause extends JqlElement {
enum Type {
- EQ,
- NE,
- LT,
- GT,
- LE,
- GE,
- CONTAINS,
- NOT_CONTAINS,
- IS,
- IS_NOT,
- IN,
- NOT_IN,
- WAS,
- WAS_IN,
- WAS_NOT,
- WAS_NOT_IN,
- CHANGED;
+ EQ(false),
+ NE(false),
+ LT(false),
+ GT(false),
+ LE(false),
+ GE(false),
+ CONTAINS(false),
+ NOT_CONTAINS(false),
+ IS(false),
+ IS_NOT(false),
+ IN(true),
+ NOT_IN(true),
+ WAS(false),
+ WAS_IN(true),
+ WAS_NOT(false),
+ WAS_NOT_IN(true),
+ CHANGED(false);
+
+ private boolean myListOperator;
+
+ Type(boolean listOperator) {
+ myListOperator = listOperator;
+ }
private final static IdentityHashMap<IElementType, Type> MAP = new IdentityHashMap<IElementType, Type>();
+
static {
MAP.put(JqlTokenTypes.EQ, EQ);
MAP.put(JqlTokenTypes.NE, NE);
@@ -47,6 +54,9 @@
return MAP.get(type);
}
+ public boolean isListOperator() {
+ return myListOperator;
+ }
}
@Nullable
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepository.java
index 9b8ba34..e3e533c 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepository.java
@@ -6,7 +6,6 @@
import com.intellij.tasks.Comment;
import com.intellij.tasks.Task;
import com.intellij.tasks.TaskRepositoryType;
-import com.intellij.tasks.actions.TaskSearchSupport;
import com.intellij.tasks.impl.BaseRepository;
import com.intellij.tasks.impl.BaseRepositoryImpl;
import com.intellij.tasks.mantis.model.*;
@@ -85,8 +84,7 @@
while (true) {
cancelled.checkCanceled();
final List<Task> issuesFromPage = getIssues(page, issuesOnPage, soap);
- final List<Task> filteredTasks = TaskSearchSupport.filterTasks(query != null ? query : "", issuesFromPage);
- tasks.addAll(filteredTasks);
+ tasks.addAll(issuesFromPage);
if (issuesFromPage.size() < issuesOnPage || tasks.size() >= max) {
break;
}
@@ -275,4 +273,9 @@
Comparing.equal(getProject(), ((MantisRepository)o).getProject()) &&
Comparing.equal(getFilter(), ((MantisRepository)o).getFilter());
}
+
+ @Override
+ protected int getFeatures() {
+ return super.getFeatures() & ~NATIVE_SEARCH;
+ }
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/pivotal/PivotalTrackerRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/pivotal/PivotalTrackerRepository.java
index 48c6054..c0d46b8 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/pivotal/PivotalTrackerRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/pivotal/PivotalTrackerRepository.java
@@ -363,6 +363,6 @@
@Override
protected int getFeatures() {
- return BASIC_HTTP_AUTHORIZATION;
+ return super.getFeatures() | BASIC_HTTP_AUTHORIZATION;
}
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java
index f2b082d..847d7b1 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java
@@ -308,6 +308,6 @@
@Override
protected int getFeatures() {
- return BASIC_HTTP_AUTHORIZATION;
+ return super.getFeatures() | BASIC_HTTP_AUTHORIZATION;
}
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/trac/TracRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/trac/TracRepository.java
index 6d9a771..19dadba 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/trac/TracRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/trac/TracRepository.java
@@ -269,6 +269,6 @@
@Override
protected int getFeatures() {
- return BASIC_HTTP_AUTHORIZATION;
+ return super.getFeatures() | BASIC_HTTP_AUTHORIZATION;
}
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepository.java
index 0430dea..80d5246 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepository.java
@@ -330,7 +330,7 @@
}
@Override
- public String getUrl() {
+ public String getPresentableName() {
String pseudoUrl = "trello.com";
if (myCurrentBoard != null) {
pseudoUrl += "/" + myCurrentBoard.getName();
@@ -353,4 +353,19 @@
}
};
}
+
+ @Override
+ public boolean isConfigured() {
+ return super.isConfigured() && StringUtil.isNotEmpty(myPassword);
+ }
+
+ @Override
+ public String getUrl() {
+ return "trello.com";
+ }
+
+ @Override
+ protected int getFeatures() {
+ return super.getFeatures() & ~NATIVE_SEARCH;
+ }
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepositoryType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepositoryType.java
index 3fb032d..86fca7a 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepositoryType.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepositoryType.java
@@ -18,8 +18,8 @@
import com.intellij.openapi.project.Project;
import com.intellij.tasks.TaskRepository;
-import com.intellij.tasks.TaskRepositoryType;
import com.intellij.tasks.config.TaskRepositoryEditor;
+import com.intellij.tasks.impl.BaseRepositoryType;
import com.intellij.util.Consumer;
import icons.TasksIcons;
import org.jetbrains.annotations.NotNull;
@@ -30,7 +30,7 @@
/**
* @author Mikhail Golubev
*/
-public class TrelloRepositoryType extends TaskRepositoryType<TrelloRepository> {
+public class TrelloRepositoryType extends BaseRepositoryType<TrelloRepository> {
public static final String DEVELOPER_KEY = "d6ec3709f7141007e150de64d4701181";
public static final String CLIENT_AUTHORIZATION_URL =
"https://trello.com/1/authorize?key=" + DEVELOPER_KEY +"&name=JetBrains&expiration=never&response_type=token";
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java
index 1ff6d9d..44fa593 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java
@@ -317,6 +317,6 @@
@Override
protected int getFeatures() {
- return TIME_MANAGEMENT;
+ return super.getFeatures() | TIME_MANAGEMENT;
}
}
diff --git a/plugins/tasks/tasks-core/src/icons/TasksIcons.java b/plugins/tasks/tasks-core/src/icons/TasksIcons.java
index b089872..3313ba8 100644
--- a/plugins/tasks/tasks-core/src/icons/TasksIcons.java
+++ b/plugins/tasks/tasks-core/src/icons/TasksIcons.java
@@ -40,6 +40,7 @@
public static final Icon Trac = load("/icons/trac.png"); // 16x16
public static final Icon Unknown = load("/icons/unknown.png"); // 16x16
public static final Icon Youtrack = load("/icons/youtrack.png"); // 16x16
+ public static final Icon Asana = load("/icons/asana.png"); // 16x16
public static final Icon Trello = load("/icons/trello.png"); // 16x16
public static final Icon JIRA = load("/icons/jira.png"); // 16x16
}
diff --git a/plugins/tasks/tasks-core/src/icons/asana.png b/plugins/tasks/tasks-core/src/icons/asana.png
new file mode 100644
index 0000000..25cea96
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/icons/asana.png
Binary files differ
diff --git a/plugins/tasks/tasks-core/tasks-core.iml b/plugins/tasks/tasks-core/tasks-core.iml
index 707b452..11c3bc9 100644
--- a/plugins/tasks/tasks-core/tasks-core.iml
+++ b/plugins/tasks/tasks-core/tasks-core.iml
@@ -27,8 +27,38 @@
</orderEntry>
<orderEntry type="library" exported="" name="http-client-3.1" level="project" />
<orderEntry type="library" name="XmlRPC" level="project" />
+ <orderEntry type="module-library" exported="">
+ <library name="markdownj">
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/markdownj-core-0.4.2-SNAPSHOT.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
<orderEntry type="library" name="gson" level="project" />
<orderEntry type="module" module-name="xml" />
+ <orderEntry type="module" module-name="core-api" />
+ <orderEntry type="module" module-name="xpath" />
+ <orderEntry type="module" module-name="RegExpSupport" />
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/json-path-0.8.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/json-smart-1.1.1.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
@@ -41,7 +71,6 @@
<orderEntry type="module" module-name="xdebugger-api" />
<orderEntry type="module" module-name="xdebugger-impl" />
<orderEntry type="library" exported="" name="markdownj" level="project" />
- <orderEntry type="module" module-name="core-api" />
</component>
</module>
diff --git a/plugins/tasks/tasks-tests/tasks-tests.iml b/plugins/tasks/tasks-tests/tasks-tests.iml
index deeddcc..a1d5001 100644
--- a/plugins/tasks/tasks-tests/tasks-tests.iml
+++ b/plugins/tasks/tasks-tests/tasks-tests.iml
@@ -18,6 +18,8 @@
<orderEntry type="module" module-name="xslt-debugger" />
<orderEntry type="module" module-name="xdebugger-impl" scope="TEST" />
<orderEntry type="module" module-name="git4idea" scope="TEST" />
+ <orderEntry type="module" module-name="remote-servers-impl" scope="TEST" />
+ <orderEntry type="module" module-name="manifest" scope="TEST" />
</component>
</module>
diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AsanaGenericIntegrationTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AsanaGenericIntegrationTest.java
new file mode 100644
index 0000000..1a6d3bf
--- /dev/null
+++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AsanaGenericIntegrationTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.tasks.integration;
+
+import com.intellij.tasks.Task;
+import com.intellij.tasks.TaskManagerTestCase;
+import com.intellij.tasks.generic.GenericRepository;
+import com.intellij.tasks.generic.GenericRepositoryType;
+import com.intellij.tasks.generic.GenericTask;
+import com.intellij.util.containers.ContainerUtil;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class AsanaGenericIntegrationTest extends TaskManagerTestCase {
+ private static final String RESPONSE = "" +
+ "{\n" +
+ " \"data\": [\n" +
+ " {\n" +
+ " \"id\": 5479650606120,\n" +
+ " \"name\": \"Task #1\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"id\": 5202014833559,\n" +
+ " \"name\": \"Task #2\"\n" +
+ " }\n" +
+ " ]\n" +
+ "}";
+
+ private GenericRepository myRepository;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ GenericRepositoryType genericType = new GenericRepositoryType();
+ myRepository = (GenericRepository) genericType.new AsanaRepository().createRepository();
+ }
+
+ public void testParsing() throws Exception {
+ Task[] tasks = myRepository.getActiveResponseHandler().parseIssues(RESPONSE);
+ List<Task> expected = ContainerUtil.<Task>newArrayList(
+ new GenericTask("5479650606120", "Task #1", myRepository),
+ new GenericTask("5202014833559", "Task #2", myRepository)
+ );
+ assertEquals(expected, Arrays.asList(tasks));
+ }
+}
diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AssemblaIntegrationTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AssemblaIntegrationTest.java
index 1f26161..43a8af6 100644
--- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AssemblaIntegrationTest.java
+++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/AssemblaIntegrationTest.java
@@ -26,42 +26,44 @@
*/
public class AssemblaIntegrationTest extends TaskManagerTestCase {
+ public static final String RESPONSE =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<tickets type=\"array\">\n" +
+ "<ticket>\n" +
+ " <assigned-to-id>dsNkyYr0Gr4iEBeJe5cbCb</assigned-to-id>\n" +
+ " <completed-date type=\"datetime\"></completed-date>\n" +
+ " <component-id type=\"integer\"></component-id>\n" +
+ " <created-on type=\"datetime\">2013-04-01T10:45:06+03:00</created-on>\n" +
+ " <description></description>\n" +
+ " <from-support type=\"integer\">0</from-support>\n" +
+ " <id type=\"integer\">50351983</id>\n" +
+ " <importance type=\"integer\">-1</importance>\n" +
+ " <importance-float type=\"float\">-1.0</importance-float>\n" +
+ " <is-story type=\"boolean\">false</is-story>\n" +
+ " <milestone-id type=\"integer\"></milestone-id>\n" +
+ " <notification-list>dsNkyYr0Gr4iEBeJe5cbCb</notification-list>\n" +
+ " <number type=\"integer\">1</number>\n" +
+ " <priority type=\"integer\">3</priority>\n" +
+ " <reporter-id>dsNkyYr0Gr4iEBeJe5cbCb</reporter-id>\n" +
+ " <space-id>ab1WOCMQar4QGgacwqjQWU</space-id>\n" +
+ " <status type='integer'>0</status>\n" +
+ " <status-name>New</status-name>\n" +
+ " <story-importance type=\"integer\">0</story-importance>\n" +
+ " <summary>Привет</summary>\n" +
+ " <updated-at type=\"datetime\">2013-04-01T10:48:19+03:00</updated-at>\n" +
+ " <working-hours type=\"float\">0.0</working-hours>\n" +
+ " <working-hour type=\"float\" warning=\"deprecated\">0.0</working-hour>\n" +
+ " <estimate type=\"string\">Small</estimate>\n" +
+ " <total-estimate type=\"float\">1.0</total-estimate>\n" +
+ " <invested-hours type=\"float\">0.0</invested-hours>\n" +
+ " <assigned-to><id>dsNkyYr0Gr4iEBeJe5cbCb</id><login>avdeev.dmitry</login><login_name warning=\"deprecated\">avdeev.dmitry</login_name><name>avdeev.dmitry</name></assigned-to>\n" +
+ " <reporter><id>dsNkyYr0Gr4iEBeJe5cbCb</id><login>avdeev.dmitry</login><login_name warning=\"deprecated\">avdeev.dmitry</login_name><name>avdeev.dmitry</name></reporter>\n" +
+ "</ticket>\n" +
+ "</tickets>";
+
public void testParseCyrillic() throws Exception {
-
- Task[] tasks = new AssemblaRepository(new AssemblaRepositoryType()).parseResponse("", 100, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
- "<tickets type=\"array\">\n" +
- "<ticket>\n" +
- " <assigned-to-id>dsNkyYr0Gr4iEBeJe5cbCb</assigned-to-id>\n" +
- " <completed-date type=\"datetime\"></completed-date>\n" +
- " <component-id type=\"integer\"></component-id>\n" +
- " <created-on type=\"datetime\">2013-04-01T10:45:06+03:00</created-on>\n" +
- " <description></description>\n" +
- " <from-support type=\"integer\">0</from-support>\n" +
- " <id type=\"integer\">50351983</id>\n" +
- " <importance type=\"integer\">-1</importance>\n" +
- " <importance-float type=\"float\">-1.0</importance-float>\n" +
- " <is-story type=\"boolean\">false</is-story>\n" +
- " <milestone-id type=\"integer\"></milestone-id>\n" +
- " <notification-list>dsNkyYr0Gr4iEBeJe5cbCb</notification-list>\n" +
- " <number type=\"integer\">1</number>\n" +
- " <priority type=\"integer\">3</priority>\n" +
- " <reporter-id>dsNkyYr0Gr4iEBeJe5cbCb</reporter-id>\n" +
- " <space-id>ab1WOCMQar4QGgacwqjQWU</space-id>\n" +
- " <status type='integer'>0</status>\n" +
- " <status-name>New</status-name>\n" +
- " <story-importance type=\"integer\">0</story-importance>\n" +
- " <summary>Привет</summary>\n" +
- " <updated-at type=\"datetime\">2013-04-01T10:48:19+03:00</updated-at>\n" +
- " <working-hours type=\"float\">0.0</working-hours>\n" +
- " <working-hour type=\"float\" warning=\"deprecated\">0.0</working-hour>\n" +
- " <estimate type=\"string\">Small</estimate>\n" +
- " <total-estimate type=\"float\">1.0</total-estimate>\n" +
- " <invested-hours type=\"float\">0.0</invested-hours>\n" +
- " <assigned-to><id>dsNkyYr0Gr4iEBeJe5cbCb</id><login>avdeev.dmitry</login><login_name warning=\"deprecated\">avdeev.dmitry</login_name><name>avdeev.dmitry</name></assigned-to>\n" +
- " <reporter><id>dsNkyYr0Gr4iEBeJe5cbCb</id><login>avdeev.dmitry</login><login_name warning=\"deprecated\">avdeev.dmitry</login_name><name>avdeev.dmitry</name></reporter>\n" +
- "</ticket>\n" +
- "</tickets>");
-
+ AssemblaRepository repository = new AssemblaRepository(new AssemblaRepositoryType());
+ Task[] tasks = repository.getActiveResponseHandler().parseIssues(RESPONSE);
assertEquals(1, tasks.length);
assertEquals("\u041F\u0440\u0438\u0432\u0435\u0442", tasks[0].getSummary());
}
diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/jira/jql/CompletionTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/jira/jql/CompletionTest.java
index bf56b70..d3ee5b1 100644
--- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/jira/jql/CompletionTest.java
+++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/jira/jql/CompletionTest.java
@@ -1,18 +1,17 @@
package com.intellij.tasks.jira.jql;
import com.intellij.tasks.jira.jql.codeinsight.JqlFieldType;
-import com.intellij.tasks.jira.jql.codeinsight.JqlStandardField;
import com.intellij.tasks.jira.jql.codeinsight.JqlStandardFunction;
import com.intellij.testFramework.IdeaTestCase;
import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase;
import com.intellij.util.ArrayUtil;
-import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
+import static com.intellij.tasks.jira.jql.codeinsight.JqlStandardField.*;
+import static com.intellij.tasks.jira.jql.codeinsight.JqlStandardFunction.ALL_FUNCTION_NAMES;
+
/**
* @author Mikhail Golubev
*/
@@ -39,28 +38,16 @@
}
private void checkCompletionVariants(List<String> initial, String... others) {
- List<String> variants = new ArrayList<String>(initial);
- ContainerUtil.addAll(variants, others);
- myFixture.testCompletionVariants(getTestFilePath(), ArrayUtil.toStringArray(variants));
+ myFixture.testCompletionVariants(getTestFilePath(),
+ ArrayUtil.toStringArray(ContainerUtil.concat(true, initial, others)));
}
private void checkCompletionVariants(String... variants) {
checkCompletionVariants(ContainerUtil.<String>emptyList(), variants);
}
- private static List<String> parenthesize(Collection<String> names) {
- return ContainerUtil.map2List(names, new Function<String, String>() {
- @Override
- public String fun(String s) {
- return s + "()";
- }
- });
- }
-
- private static final List<String> PARENTHESIZED_FUNCTION_NAMES = parenthesize(JqlStandardFunction.ALL_FUNCTION_NAMES);
-
public void testBeginningOfLine() throws Exception {
- checkCompletionVariants(JqlStandardField.ALL_FIELDS_NAMES, "not");
+ checkCompletionVariants(ALL_FIELD_NAMES, "not");
}
public void testAfterClause() throws Exception {
@@ -98,44 +85,47 @@
}
public void testFunctionType1() throws Exception {
- checkCompletionVariants("membersOf()");
+ checkCompletionVariants("membersOf");
}
public void testFunctionType2() throws Exception {
- checkCompletionVariants("currentUser()");
+ checkCompletionVariants("currentUser");
}
public void testFunctionType3() throws Exception {
- checkCompletionVariants("currentUser()");
+ checkCompletionVariants("currentUser");
}
public void testFunctionType4() throws Exception {
- checkCompletionVariants(parenthesize(JqlStandardFunction.allOfType(JqlFieldType.DATE, false)));
+ checkCompletionVariants(JqlStandardFunction.allOfType(JqlFieldType.DATE, false));
}
public void testFunctionType5() throws Exception {
- checkCompletionVariants(parenthesize(JqlStandardFunction.allOfType(JqlFieldType.DATE, false)));
+ checkCompletionVariants(JqlStandardFunction.allOfType(JqlFieldType.DATE, false));
}
- /**
- * "not |" -> "not not |", "not field |"
- */
+ public void testAfterParenthesisInSubClause() throws Exception {
+ checkCompletionVariants(ALL_FIELD_NAMES, "not");
+ }
+
+ public void testFunctionArguments() throws Exception {
+ // only literals accepted so we can't assume anything
+ checkCompletionVariants(ContainerUtil.<String>emptyList());
+ }
+
public void testAfterNotKeywordInNotClause() throws Exception {
- checkCompletionVariants(JqlStandardField.ALL_FIELDS_NAMES, "not");
+ checkCompletionVariants(ALL_FIELD_NAMES, "not");
}
public void testAfterOrderKeyword() throws Exception {
checkCompletionVariants("by");
}
- /**
- * "foo was |" -> "foo was func()", "foo was not |", "foo was in |"
- */
public void testAfterWasKeyword() throws Exception {
- checkCompletionVariants(PARENTHESIZED_FUNCTION_NAMES, "not", "in");
+ checkCompletionVariants(ALL_FUNCTION_NAMES, "not", "in");
}
public void testInList() throws Exception {
- checkCompletionVariants(PARENTHESIZED_FUNCTION_NAMES);
+ checkCompletionVariants(ALL_FUNCTION_NAMES);
}
}
diff --git a/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterParenthesisInSubClause.jql b/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterParenthesisInSubClause.jql
new file mode 100644
index 0000000..66abe15
--- /dev/null
+++ b/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterParenthesisInSubClause.jql
@@ -0,0 +1 @@
+reporter = "Bob" and (<caret>)
\ No newline at end of file
diff --git a/plugins/tasks/tasks-tests/testData/jira/jql/completion/FunctionArguments.jql b/plugins/tasks/tasks-tests/testData/jira/jql/completion/FunctionArguments.jql
new file mode 100644
index 0000000..685ddbc
--- /dev/null
+++ b/plugins/tasks/tasks-tests/testData/jira/jql/completion/FunctionArguments.jql
@@ -0,0 +1 @@
+status was not someFunction(<caret>)
\ No newline at end of file
diff --git a/plugins/terminal/lib/jna-platform.jar b/plugins/terminal/lib/jna-platform.jar
new file mode 100644
index 0000000..4b3d567
--- /dev/null
+++ b/plugins/terminal/lib/jna-platform.jar
Binary files differ
diff --git a/plugins/terminal/lib/libwinpty.dll b/plugins/terminal/lib/libwinpty.dll
deleted file mode 100644
index 9a7eaf6..0000000
--- a/plugins/terminal/lib/libwinpty.dll
+++ /dev/null
Binary files differ
diff --git a/plugins/terminal/lib/linux/x86/libpty.so b/plugins/terminal/lib/linux/x86/libpty.so
new file mode 100755
index 0000000..f6d92d7
--- /dev/null
+++ b/plugins/terminal/lib/linux/x86/libpty.so
Binary files differ
diff --git a/plugins/terminal/lib/linux/x86_64/libpty.so b/plugins/terminal/lib/linux/x86_64/libpty.so
new file mode 100755
index 0000000..4417e95
--- /dev/null
+++ b/plugins/terminal/lib/linux/x86_64/libpty.so
Binary files differ
diff --git a/plugins/terminal/lib/macosx/x86/libpty.dylib b/plugins/terminal/lib/macosx/x86/libpty.dylib
new file mode 100755
index 0000000..e4f428d
--- /dev/null
+++ b/plugins/terminal/lib/macosx/x86/libpty.dylib
Binary files differ
diff --git a/plugins/terminal/lib/pty4j-0.3.jar b/plugins/terminal/lib/pty4j-0.3.jar
index 38b0470..a4d2cb9 100644
--- a/plugins/terminal/lib/pty4j-0.3.jar
+++ b/plugins/terminal/lib/pty4j-0.3.jar
Binary files differ
diff --git a/plugins/terminal/lib/winpty-agent.exe b/plugins/terminal/lib/winpty-agent.exe
deleted file mode 100644
index 87431b5..0000000
--- a/plugins/terminal/lib/winpty-agent.exe
+++ /dev/null
Binary files differ
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
index bd540bfa..dc8c410 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
@@ -4,8 +4,8 @@
import com.intellij.execution.process.*;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
@@ -16,14 +16,12 @@
import com.jediterm.terminal.TtyConnector;
import com.pty4j.PtyProcess;
import com.pty4j.util.PtyUtil;
-import com.pty4j.windows.WinPty;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
-import java.security.CodeSource;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@@ -32,6 +30,7 @@
* @author traff
*/
public class LocalTerminalDirectRunner extends AbstractTerminalRunner<PtyProcess> {
+ private static final Logger LOG = Logger.getInstance(LocalTerminalDirectRunner.class);
private final Charset myDefaultCharset;
private final String[] myCommand;
@@ -56,13 +55,18 @@
}
private static File findRCFile() {
- String folder = PtyUtil.getJarFolder();
- if (folder != null) {
- File rcFile = new File(folder, "jediterm.in");
- if (rcFile.exists()) {
- return rcFile;
+ try {
+ final String folder = PtyUtil.getJarFolder();
+ if (folder != null) {
+ File rcFile = new File(folder, "jediterm.in");
+ if (rcFile.exists()) {
+ return rcFile;
+ }
}
}
+ catch (Exception e) {
+ LOG.warn("Unable to get jar folder", e);
+ }
return null;
}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalToolWindowFactory.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalToolWindowFactory.java
index ad7d06a..7d57aac 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalToolWindowFactory.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalToolWindowFactory.java
@@ -1,5 +1,6 @@
package org.jetbrains.plugins.terminal;
+import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
@@ -7,7 +8,7 @@
/**
* @author traff
*/
-public class TerminalToolWindowFactory implements ToolWindowFactory {
+public class TerminalToolWindowFactory implements ToolWindowFactory, DumbAware {
@Override
public void createToolWindowContent(Project project, ToolWindow toolWindow) {
TerminalView terminalView = TerminalView.getInstance();
diff --git a/plugins/testng/src/META-INF/plugin.xml b/plugins/testng/src/META-INF/plugin.xml
index 0315fc3..fe64bc8 100644
--- a/plugins/testng/src/META-INF/plugin.xml
+++ b/plugins/testng/src/META-INF/plugin.xml
@@ -8,10 +8,10 @@
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
<deadCode implementation="com.theoryinpractice.testng.inspection.TestNGEntryPoint"/>
<cantBeStatic implementation="com.theoryinpractice.testng.inspection.TestNGCanBeStaticExtension" />
- <configurationProducer implementation="com.theoryinpractice.testng.configuration.TestNGPatternConfigurationProducer"/>
- <configurationProducer implementation="com.theoryinpractice.testng.configuration.TestNGInClassConfigurationProducer"/>
- <configurationProducer implementation="com.theoryinpractice.testng.configuration.TestNGPackageConfigurationProducer"/>
- <configurationProducer implementation="com.theoryinpractice.testng.configuration.TestNGSuiteConfigurationProducer"/>
+ <runConfigurationProducer implementation="com.theoryinpractice.testng.configuration.TestNGPatternConfigurationProducer"/>
+ <runConfigurationProducer implementation="com.theoryinpractice.testng.configuration.TestNGInClassConfigurationProducer"/>
+ <runConfigurationProducer implementation="com.theoryinpractice.testng.configuration.TestNGPackageConfigurationProducer"/>
+ <runConfigurationProducer implementation="com.theoryinpractice.testng.configuration.TestNGSuiteConfigurationProducer"/>
<configurationType implementation="com.theoryinpractice.testng.configuration.TestNGConfigurationType"/>
<psi.referenceContributor language="JAVA" implementation="com.theoryinpractice.testng.TestNGReferenceContributor"/>
<psi.referenceContributor language="XML" implementation="com.theoryinpractice.testng.TestNGSuiteReferenceContributor"/>
diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationProducer.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationProducer.java
index 2baeab6..5d3bbb9 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationProducer.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationProducer.java
@@ -20,50 +20,46 @@
*/
package com.theoryinpractice.testng.configuration;
-import com.intellij.execution.Location;
-import com.intellij.execution.RunManagerEx;
-import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.*;
import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.actions.RunConfigurationProducer;
+import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.impl.RunManagerImpl;
+import com.intellij.execution.junit.JUnitUtil;
+import com.intellij.execution.junit.JavaRunConfigurationProducerBase;
import com.intellij.execution.junit.JavaRuntimeConfigurationProducerBase;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.Comparing;
-import com.intellij.psi.PsiElement;
+import com.intellij.psi.*;
import com.theoryinpractice.testng.model.TestData;
import org.jetbrains.annotations.NotNull;
import java.util.List;
-public abstract class TestNGConfigurationProducer extends JavaRuntimeConfigurationProducerBase implements Cloneable {
+public abstract class TestNGConfigurationProducer extends JavaRunConfigurationProducerBase<TestNGConfiguration> implements Cloneable {
public TestNGConfigurationProducer() {
super(TestNGConfigurationType.getInstance());
}
@Override
- protected RunnerAndConfigurationSettings findExistingByElement(Location location,
- @NotNull List<RunnerAndConfigurationSettings> existingConfigurations,
- ConfigurationContext context) {
- final TestNGConfiguration testNGConfiguration =
- (TestNGConfiguration)context.getOriginalConfiguration(TestNGConfigurationType.getInstance());
- final String vmParameters = testNGConfiguration != null ? testNGConfiguration.getVMParameters() : null;
- final Module predefinedModule =
- ((TestNGConfiguration)((RunManagerImpl)RunManagerEx.getInstanceEx(location.getProject()))
- .getConfigurationTemplate(getConfigurationFactory())
- .getConfiguration()).getConfigurationModule().getModule();
- for (RunnerAndConfigurationSettings existingConfiguration : existingConfigurations) {
- TestNGConfiguration config = (TestNGConfiguration)existingConfiguration.getConfiguration();
- if (vmParameters != null && !Comparing.strEqual(config.getVMParameters(), vmParameters)) continue;
- TestData testobject = config.getPersistantData();
- if (testobject != null){
- final PsiElement element = location.getPsiElement();
- if (testobject.isConfiguredByElement(element)) {
- final Module configurationModule = config.getConfigurationModule().getModule();
- if (Comparing.equal(location.getModule(), configurationModule)) return existingConfiguration;
- if (Comparing.equal(predefinedModule, configurationModule)) return existingConfiguration;
- }
+ public boolean isConfigurationFromContext(TestNGConfiguration testNGConfiguration, ConfigurationContext context) {
+ final RunConfiguration predefinedConfiguration = context.getOriginalConfiguration(TestNGConfigurationType.getInstance());
+ Location location = JavaExecutionUtil.stepIntoSingleClass(context.getLocation());
+ final PsiElement element = location.getPsiElement();
+ RunnerAndConfigurationSettings template = RunManager.getInstance(location.getProject()).getConfigurationTemplate(getConfigurationFactory());
+ final Module predefinedModule = ((TestNGConfiguration)template.getConfiguration()).getConfigurationModule().getModule();
+ final String vmParameters =
+ predefinedConfiguration instanceof TestNGConfiguration ? ((TestNGConfiguration)predefinedConfiguration).getVMParameters() : null;
+ if (vmParameters != null && !Comparing.strEqual(vmParameters, testNGConfiguration.getVMParameters())) return false;
+ TestData testobject = testNGConfiguration.getPersistantData();
+ if (testobject != null) {
+ if (testobject.isConfiguredByElement(element)) {
+ final Module configurationModule = testNGConfiguration.getConfigurationModule().getModule();
+ if (Comparing.equal(location.getModule(), configurationModule)) return true;
+ if (Comparing.equal(predefinedModule, configurationModule)) return true;
}
}
- return null;
+ return false;
}
}
\ No newline at end of file
diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGInClassConfigurationProducer.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGInClassConfigurationProducer.java
index 815a847..b613e1d 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGInClassConfigurationProducer.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGInClassConfigurationProducer.java
@@ -25,14 +25,20 @@
import com.intellij.execution.PsiLocation;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.actions.ConfigurationFromContext;
import com.intellij.execution.junit.InheritorChooser;
+import com.intellij.execution.junit.JUnitUtil;
+import com.intellij.execution.junit.JavaRuntimeConfigurationProducerBase;
+import com.intellij.execution.junit2.info.LocationUtil;
import com.intellij.execution.junit2.info.MethodLocation;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiClassUtil;
import com.intellij.psi.util.PsiTreeUtil;
+import com.theoryinpractice.testng.model.TestData;
import com.theoryinpractice.testng.util.TestNGUtil;
import org.jetbrains.annotations.Nullable;
@@ -41,74 +47,12 @@
public class TestNGInClassConfigurationProducer extends TestNGConfigurationProducer{
private PsiElement myPsiElement = null;
- public PsiElement getSourceElement() {
- return myPsiElement;
- }
-
- @Nullable
- protected RunnerAndConfigurationSettings createConfigurationByElement(Location location, ConfigurationContext context) {
- final PsiElement[] elements = context != null ? LangDataKeys.PSI_ELEMENT_ARRAY.getData(context.getDataContext()) : null;
- if (elements != null && TestNGPatternConfigurationProducer.collectTestMembers(elements).size() > 1) {
- return null;
- }
-
- PsiClass psiClass = null;
- PsiElement element = location.getPsiElement();
- while (element != null) {
- if (element instanceof PsiClass && isTestNGClass((PsiClass)element)) {
- psiClass = (PsiClass)element;
- break;
- }
- else if (element instanceof PsiMember) {
- psiClass = ((PsiMember)element).getContainingClass();
- if (isTestNGClass(psiClass)) {
- break;
- }
- }
- else if (element instanceof PsiClassOwner) {
- final PsiClass[] classes = ((PsiClassOwner)element).getClasses();
- if (classes.length == 1) {
- psiClass = classes[0];
- break;
- }
- }
- element = element.getParent();
- }
- if (!isTestNGClass(psiClass)) return null;
-
- myPsiElement = psiClass;
- final Project project = location.getProject();
- RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(project, context);
- final TestNGConfiguration configuration = (TestNGConfiguration)settings.getConfiguration();
- setupConfigurationModule(context, configuration);
- final Module originalModule = configuration.getConfigurationModule().getModule();
- configuration.setClassConfiguration(psiClass);
-
- PsiMethod method = PsiTreeUtil.getParentOfType(location.getPsiElement(), PsiMethod.class, false);
- while (method != null) {
- if (TestNGUtil.hasTest(method)) {
- configuration.setMethodConfiguration(PsiLocation.fromPsiElement(project, method));
- myPsiElement = method;
- }
- method = PsiTreeUtil.getParentOfType(method, PsiMethod.class);
- }
-
- configuration.restoreOriginalModule(originalModule);
- settings.setName(configuration.getName());
- JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location);
- return settings;
- }
-
private static boolean isTestNGClass(PsiClass psiClass) {
return psiClass != null && PsiClassUtil.isRunnableClass(psiClass, true, false) && TestNGUtil.hasTest(psiClass);
}
- public int compareTo(Object o) {
- return PREFERED;
- }
-
@Override
- public void perform(final ConfigurationContext context, final Runnable performRunnable) {
+ public void onFirstRun(ConfigurationFromContext configuration, ConfigurationContext fromContext, Runnable performRunnable) {
if (myPsiElement instanceof PsiMethod || myPsiElement instanceof PsiClass) {
final PsiMethod psiMethod;
@@ -144,8 +88,63 @@
super.runForClass(aClass, psiMethod, context, performRunnable);
}
};
- if (inheritorChooser.runMethodInAbstractClass(context, performRunnable, psiMethod, containingClass)) return;
+ if (inheritorChooser.runMethodInAbstractClass(fromContext, performRunnable, psiMethod, containingClass)) return;
}
- super.perform(context, performRunnable);
+ super.onFirstRun(configuration, fromContext, performRunnable);
+ }
+
+ @Override
+ protected boolean setupConfigurationFromContext(TestNGConfiguration configuration,
+ ConfigurationContext context,
+ Ref<PsiElement> sourceElement) {
+ final PsiElement[] elements = context != null ? LangDataKeys.PSI_ELEMENT_ARRAY.getData(context.getDataContext()) : null;
+ if (elements != null && TestNGPatternConfigurationProducer.collectTestMembers(elements).size() > 1) {
+ return false;
+ }
+
+ PsiClass psiClass = null;
+ PsiElement element = context.getPsiLocation();
+ while (element != null) {
+ if (element instanceof PsiClass && isTestNGClass((PsiClass)element)) {
+ psiClass = (PsiClass)element;
+ break;
+ }
+ else if (element instanceof PsiMember) {
+ psiClass = ((PsiMember)element).getContainingClass();
+ if (isTestNGClass(psiClass)) {
+ break;
+ }
+ }
+ else if (element instanceof PsiClassOwner) {
+ final PsiClass[] classes = ((PsiClassOwner)element).getClasses();
+ if (classes.length == 1) {
+ psiClass = classes[0];
+ break;
+ }
+ }
+ element = element.getParent();
+ }
+ if (!isTestNGClass(psiClass)) return false;
+
+ myPsiElement = psiClass;
+ final Project project = context.getProject();
+ RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(context);
+ setupConfigurationModule(context, configuration);
+ final Module originalModule = configuration.getConfigurationModule().getModule();
+ configuration.setClassConfiguration(psiClass);
+
+ PsiMethod method = PsiTreeUtil.getParentOfType(context.getPsiLocation(), PsiMethod.class, false);
+ while (method != null) {
+ if (TestNGUtil.hasTest(method)) {
+ configuration.setMethodConfiguration(PsiLocation.fromPsiElement(project, method));
+ myPsiElement = method;
+ }
+ method = PsiTreeUtil.getParentOfType(method, PsiMethod.class);
+ }
+
+ configuration.restoreOriginalModule(originalModule);
+ settings.setName(configuration.getName());
+ sourceElement.set(myPsiElement);
+ return true;
}
}
\ No newline at end of file
diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPackageConfigurationProducer.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPackageConfigurationProducer.java
index 5bf6ac9..3939e0c 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPackageConfigurationProducer.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPackageConfigurationProducer.java
@@ -19,8 +19,10 @@
import com.intellij.execution.Location;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.junit.JavaRuntimeConfigurationProducerBase;
import com.intellij.execution.junit2.info.LocationUtil;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPackage;
import com.theoryinpractice.testng.model.TestData;
@@ -28,30 +30,23 @@
import com.theoryinpractice.testng.util.TestNGUtil;
public class TestNGPackageConfigurationProducer extends TestNGConfigurationProducer {
- private PsiPackage myPackage = null;
- protected RunnerAndConfigurationSettings createConfigurationByElement(final Location location, final ConfigurationContext context) {
- final Project project = location.getProject();
- final PsiElement element = location.getPsiElement();
- myPackage = checkPackage(element);
- if (myPackage == null) return null;
- if (!LocationUtil.isJarAttached(location, myPackage, TestNGUtil.TEST_ANNOTATION_FQN)) return null;
- RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(project, context);
- final TestNGConfiguration configuration = (TestNGConfiguration)settings.getConfiguration();
+ @Override
+ protected boolean setupConfigurationFromContext(TestNGConfiguration configuration,
+ ConfigurationContext context,
+ Ref<PsiElement> sourceElement) {
+ final PsiElement element = context.getPsiLocation();
+ PsiPackage aPackage = JavaRuntimeConfigurationProducerBase.checkPackage(element);
+ if (aPackage == null) return false;
+ final Location location = context.getLocation();
+ if (!LocationUtil.isJarAttached(location, aPackage, TestNGUtil.TEST_ANNOTATION_FQN)) return false;
final TestData data = configuration.data;
- data.PACKAGE_NAME = myPackage.getQualifiedName();
+ data.PACKAGE_NAME = aPackage.getQualifiedName();
data.TEST_OBJECT = TestType.PACKAGE.getType();
- data.setScope(setupPackageConfiguration(context, project, configuration, data.getScope()));
+ data.setScope(setupPackageConfiguration(context, configuration, data.getScope()));
configuration.setGeneratedName();
- JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location);
- return settings;
+ sourceElement.set(aPackage);
+ return true;
}
- public PsiElement getSourceElement() {
- return myPackage;
- }
-
- public int compareTo(final Object o) {
- return PREFERED;
- }
}
\ No newline at end of file
diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPatternConfigurationProducer.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPatternConfigurationProducer.java
index 0866157..cc6d307 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPatternConfigurationProducer.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGPatternConfigurationProducer.java
@@ -33,6 +33,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
import com.theoryinpractice.testng.model.TestData;
import com.theoryinpractice.testng.model.TestType;
@@ -45,27 +46,20 @@
public class TestNGPatternConfigurationProducer extends TestNGConfigurationProducer{
- private PsiElement[] myElements;
-
-
- public int compareTo(Object o) {
- return PREFERED;
- }
-
- protected RunnerAndConfigurationSettings createConfigurationByElement(final Location location, final ConfigurationContext context) {
- final Project project = location.getProject();
+ @Override
+ protected boolean setupConfigurationFromContext(TestNGConfiguration configuration,
+ ConfigurationContext context,
+ Ref<PsiElement> sourceElement) {
final LinkedHashSet<String> classes = new LinkedHashSet<String>();
- myElements = collectPatternElements(context, classes);
- if (classes.size() <= 1) return null;
- RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(project, context);
- final TestNGConfiguration configuration = (TestNGConfiguration)settings.getConfiguration();
+ PsiElement[] elements = collectPatternElements(context, classes);
+ if (classes.size() <= 1) return false;
final TestData data = configuration.getPersistantData();
data.setPatterns(classes);
data.TEST_OBJECT = TestType.PATTERN.getType();
- data.setScope(setupPackageConfiguration(context, project, configuration, data.getScope()));
+ data.setScope(setupPackageConfiguration(context, configuration, data.getScope()));
configuration.setGeneratedName();
- JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location);
- return settings;
+ sourceElement.set(elements[0]);
+ return true;
}
static Set<PsiMember> collectTestMembers(PsiElement[] psiElements) {
@@ -115,13 +109,9 @@
return null;
}
- public PsiElement getSourceElement() {
- return myElements[0];
- }
-
@Override
- protected Module findModule(ModuleBasedConfiguration configuration, Module contextModule) {
- final Set<String> patterns = ((TestNGConfiguration)configuration).data.getPatterns();
+ protected Module findModule(TestNGConfiguration configuration, Module contextModule) {
+ final Set<String> patterns = configuration.data.getPatterns();
return findModule(configuration, contextModule, patterns);
}
@@ -135,20 +125,14 @@
}
@Override
- protected RunnerAndConfigurationSettings findExistingByElement(@NotNull Location location,
- @NotNull List<RunnerAndConfigurationSettings> existingConfigurations,
- ConfigurationContext context) {
+ public boolean isConfigurationFromContext(TestNGConfiguration testNGConfiguration, ConfigurationContext context) {
final LinkedHashSet<String> classes = new LinkedHashSet<String>();
collectPatternElements(context, classes);
- for (RunnerAndConfigurationSettings existingConfiguration : existingConfigurations) {
- final TestNGConfiguration unitConfiguration = (TestNGConfiguration)existingConfiguration.getConfiguration();
- final String type = unitConfiguration.getPersistantData().TEST_OBJECT;
- if (Comparing.equal(type, TestType.PATTERN.getType())) {
- if (Comparing.equal(classes, unitConfiguration.getPersistantData().getPatterns())) {
- return existingConfiguration;
- }
- }
+ final String type = testNGConfiguration.getPersistantData().TEST_OBJECT;
+ if (Comparing.equal(type, TestType.PATTERN.getType()) &&
+ Comparing.equal(classes, testNGConfiguration.getPersistantData().getPatterns())) {
+ return true;
}
- return null;
+ return false;
}
}
\ No newline at end of file
diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGSuiteConfigurationProducer.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGSuiteConfigurationProducer.java
index eeebd5a..707ebe3 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGSuiteConfigurationProducer.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGSuiteConfigurationProducer.java
@@ -26,6 +26,7 @@
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -34,25 +35,19 @@
import org.jetbrains.annotations.Nullable;
public class TestNGSuiteConfigurationProducer extends TestNGConfigurationProducer{
- private PsiElement myPsiElement = null;
- public PsiElement getSourceElement() {
- return myPsiElement;
- }
-
- @Nullable
- protected RunnerAndConfigurationSettings createConfigurationByElement(Location location, ConfigurationContext context) {
- final PsiElement element = location.getPsiElement();
- final PsiFile containingFile = element.getContainingFile();
- if (containingFile == null) return null;
+ @Override
+ protected boolean setupConfigurationFromContext(TestNGConfiguration configuration,
+ ConfigurationContext context,
+ Ref<PsiElement> sourceElement) {
+ final PsiElement element = context.getPsiLocation();
+ final PsiFile containingFile = element != null ? element.getContainingFile() : null;
+ if (containingFile == null) return false;
final VirtualFile virtualFile = containingFile.getVirtualFile();
- if (virtualFile == null || !virtualFile.isValid()) return null;
- if (!TestNGUtil.isTestngXML(virtualFile)) return null;
- myPsiElement = containingFile;
- final Project project = location.getProject();
- RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(project, context);
- final TestNGConfiguration configuration = (TestNGConfiguration)settings.getConfiguration();
+ if (virtualFile == null || !virtualFile.isValid()) return false;
+ if (!TestNGUtil.isTestngXML(virtualFile)) return false;
+ RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(context);
setupConfigurationModule(context, configuration);
final Module originalModule = configuration.getConfigurationModule().getModule();
configuration.getPersistantData().SUITE_NAME = virtualFile.getPath();
@@ -60,11 +55,7 @@
configuration.restoreOriginalModule(originalModule);
configuration.setGeneratedName();
settings.setName(configuration.getName());
- JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location);
- return settings;
- }
-
- public int compareTo(Object o) {
- return PREFERED;
+ sourceElement.set(containingFile);
+ return true;
}
}
\ No newline at end of file
diff --git a/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java b/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java
index 6ac43af..b83e65c 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java
@@ -30,7 +30,6 @@
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.*;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.search.GlobalSearchScope;
@@ -245,7 +244,7 @@
private static boolean isBrokenPsiClass(PsiClass psiClass) {
return (psiClass == null
|| psiClass instanceof PsiAnonymousClass
- || psiClass instanceof JspClass);
+ || psiClass instanceof PsiSyntheticClass);
}
/**
diff --git a/plugins/testng/testSources/com/theoryinpractice/testng/configuration/ConfigurationsTest.java b/plugins/testng/testSources/com/theoryinpractice/testng/configuration/ConfigurationsTest.java
index e0a3054..fae7cec 100644
--- a/plugins/testng/testSources/com/theoryinpractice/testng/configuration/ConfigurationsTest.java
+++ b/plugins/testng/testSources/com/theoryinpractice/testng/configuration/ConfigurationsTest.java
@@ -20,13 +20,19 @@
*/
package com.theoryinpractice.testng.configuration;
+import com.intellij.execution.Location;
import com.intellij.execution.PsiLocation;
import com.intellij.execution.RunManagerEx;
import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.actions.ConfigurationFromContext;
import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.PluginPathManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.JavaPsiFacade;
@@ -35,6 +41,7 @@
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.RefactoringFactory;
import com.intellij.refactoring.RenameRefactoring;
+import com.intellij.testFramework.MapDataContext;
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.intellij.testFramework.fixtures.*;
import com.intellij.util.PathUtil;
@@ -187,8 +194,16 @@
final Project project = myProjectFixture.getProject();
final PsiClass psiClass = findTestClass(project);
final TestNGInClassConfigurationProducer producer = new TestNGInClassConfigurationProducer();
- final RunnerAndConfigurationSettings config = producer.createConfigurationByElement(new PsiLocation<PsiClass>(project, psiClass), null);
- assert config != null;
+
+ final MapDataContext dataContext = new MapDataContext();
+
+ dataContext.put(PlatformDataKeys.PROJECT, project);
+ dataContext.put(LangDataKeys.MODULE, ModuleUtil.findModuleForPsiElement(psiClass));
+ dataContext.put(Location.DATA_KEY, PsiLocation.fromPsiElement(psiClass));
+
+ final ConfigurationFromContext fromContext = producer.createConfigurationFromContext(ConfigurationContext.getFromContext(dataContext));
+ assert fromContext != null;
+ final RunnerAndConfigurationSettings config = fromContext.getConfigurationSettings();
final RunConfiguration runConfiguration = config.getConfiguration();
Assert.assertTrue(runConfiguration instanceof TestNGConfiguration);
diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/psi/impl/XsltLanguage.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/psi/impl/XsltLanguage.java
index e71dd73..2667907 100644
--- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/psi/impl/XsltLanguage.java
+++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/psi/impl/XsltLanguage.java
@@ -47,12 +47,12 @@
LanguageFindUsages.INSTANCE.addExplicitExtension(this, new MyFindUsagesProvider());
LanguageRefactoringSupport.INSTANCE.addExplicitExtension(this, new RefactoringSupportProvider() {
@Override
- public boolean isInplaceRenameAvailable(PsiElement element, PsiElement context) {
+ public boolean isInplaceRenameAvailable(@NotNull PsiElement element, PsiElement context) {
return element instanceof XsltVariable && element.getUseScope() instanceof LocalSearchScope;
}
@Override
- public boolean isSafeDeleteAvailable(PsiElement element) {
+ public boolean isSafeDeleteAvailable(@NotNull PsiElement element) {
return element instanceof XPathVariable ||
element instanceof XsltTemplate;
}
diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/refactoring/XPathRefactoringSupportProvider.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/refactoring/XPathRefactoringSupportProvider.java
index 677e7e1..9561b4a 100644
--- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/refactoring/XPathRefactoringSupportProvider.java
+++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/refactoring/XPathRefactoringSupportProvider.java
@@ -49,7 +49,7 @@
}
@Override
- public boolean isInplaceRenameAvailable(PsiElement element, PsiElement context) {
+ public boolean isInplaceRenameAvailable(@NotNull PsiElement element, PsiElement context) {
return element instanceof XsltVariable && element.getUseScope() instanceof LocalSearchScope;
}
@@ -69,7 +69,7 @@
}
@Override
- public boolean isSafeDeleteAvailable(PsiElement element) {
+ public boolean isSafeDeleteAvailable(@NotNull PsiElement element) {
return element instanceof XPathVariable ||
element instanceof XsltTemplate;
}
diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/run/XsltRunConfiguration.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/run/XsltRunConfiguration.java
index 8e528e3..b45a088 100644
--- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/run/XsltRunConfiguration.java
+++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/run/XsltRunConfiguration.java
@@ -68,7 +68,6 @@
private static final String RELAXED_FILE_PATH_EXPR = "((?:file\\://?)?(?:/?\\p{Alpha}\\:)?(?:/\\p{Alpha}\\:)?[^:]+)";
private static final String LOG_TAG = "(?:\\[[\\w ]+\\]\\:? +)?";
- private static final VirtualFilePointerManager FILE_POINTER_MANAGER = VirtualFilePointerManager.getInstance();
public enum OutputType {
CONSOLE, STDOUT, @Deprecated FILE
@@ -173,8 +172,8 @@
public final RunConfiguration clone() {
final XsltRunConfiguration configuration = (XsltRunConfiguration)super.clone();
configuration.myParameters = new ArrayList<Pair<String, String>>(myParameters);
- if (myXsltFile != null) configuration.myXsltFile = FILE_POINTER_MANAGER.duplicate(myXsltFile, getProject(), null);
- if (myXmlInputFile != null) configuration.myXmlInputFile = FILE_POINTER_MANAGER.duplicate(myXmlInputFile, getProject(), null);
+ if (myXsltFile != null) configuration.myXsltFile = VirtualFilePointerManager.getInstance().duplicate(myXsltFile, getProject(), null);
+ if (myXmlInputFile != null) configuration.myXmlInputFile = VirtualFilePointerManager.getInstance().duplicate(myXmlInputFile, getProject(), null);
return configuration;
}
@@ -229,14 +228,14 @@
if (e != null) {
final String url = e.getAttributeValue("url");
if (url != null) {
- myXsltFile = FILE_POINTER_MANAGER.create(url, getProject(), null);
+ myXsltFile = VirtualFilePointerManager.getInstance().create(url, getProject(), null);
}
}
e = element.getChild("XmlFile");
if (e != null) {
final String url = e.getAttributeValue("url");
if (url != null) {
- myXmlInputFile = FILE_POINTER_MANAGER.create(url, getProject(), null);
+ myXmlInputFile = VirtualFilePointerManager.getInstance().create(url, getProject(), null);
}
}
@@ -349,12 +348,12 @@
if (isEmpty(xsltFile)) {
myXsltFile = null;
} else {
- myXsltFile = FILE_POINTER_MANAGER.create(VfsUtilCore.pathToUrl(xsltFile).replace(File.separatorChar, '/'), getProject(), null);
+ myXsltFile = VirtualFilePointerManager.getInstance().create(VfsUtilCore.pathToUrl(xsltFile).replace(File.separatorChar, '/'), getProject(), null);
}
}
private void setXsltFile(VirtualFile virtualFile) {
- myXsltFile = FILE_POINTER_MANAGER.create(virtualFile, getProject(), null);
+ myXsltFile = VirtualFilePointerManager.getInstance().create(virtualFile, getProject(), null);
}
@Nullable
@@ -400,12 +399,12 @@
if (isEmpty(xmlInputFile)) {
myXmlInputFile = null;
} else {
- myXmlInputFile = FILE_POINTER_MANAGER.create(VfsUtilCore.pathToUrl(xmlInputFile).replace(File.separatorChar, '/'), getProject(), null);
+ myXmlInputFile = VirtualFilePointerManager.getInstance().create(VfsUtilCore.pathToUrl(xmlInputFile).replace(File.separatorChar, '/'), getProject(), null);
}
}
public void setXmlInputFile(VirtualFile xmlInputFile) {
- myXmlInputFile = FILE_POINTER_MANAGER.create(xmlInputFile, getProject(), null);
+ myXmlInputFile = VirtualFilePointerManager.getInstance().create(xmlInputFile, getProject(), null);
}
public void setModule(Module module) {
diff --git a/resources/resources.iml b/resources/resources.iml
index cdb317e..1f8b3f2 100644
--- a/resources/resources.iml
+++ b/resources/resources.iml
@@ -12,7 +12,6 @@
<orderEntry type="module" module-name="images" exported="" />
<orderEntry type="module" module-name="community-resources" exported="" />
<orderEntry type="module" module-name="util" />
- <orderEntry type="module" module-name="remote-servers-impl" exported="" scope="RUNTIME" />
</component>
<component name="copyright">
<Base>
diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml
index 27c7454..58281cf 100644
--- a/resources/src/META-INF/IdeaPlugin.xml
+++ b/resources/src/META-INF/IdeaPlugin.xml
@@ -222,6 +222,8 @@
<extensionPoint name="java.compilerOutputIndex" area="IDEA_PROJECT"
interface="com.intellij.compilerOutputIndex.api.indexer.CompilerOutputBaseIndex"/>
<extensionPoint name="vetoSPICondition" interface="com.intellij.openapi.util.Condition"/>
+
+ <extensionPoint name="manifest.parser.provider" interface="org.jetbrains.lang.manifest.header.HeaderParserProvider"/>
</extensionPoints>
<extensions defaultExtensionNs="com.intellij">
@@ -1376,6 +1378,9 @@
<debugger.breakpointFactory implementation="com.intellij.debugger.ui.breakpoints.MethodBreakpointFactory"/>
<debugger.jvmSmartStepIntoHandler implementation="com.intellij.debugger.actions.JavaSmartStepIntoHandler"/>
+ <applicationService serviceInterface="com.intellij.remoteServer.runtime.deployment.debug.JavaDebuggerLauncher"
+ serviceImplementation="com.intellij.remoteServer.impl.runtime.deployment.debug.JavaDebuggerLauncherImpl"/>
+
<dom.uiControlsProvider implementation="com.intellij.util.xml.impl.JavaDomApplicationComponent"/>
<programRunner id="defaultDebugRunner" implementation="com.intellij.debugger.impl.GenericDebuggerRunner" order="last"/>
@@ -1427,10 +1432,28 @@
<writingAccessProvider implementation="com.intellij.refactoring.util.ClsElementWritingAccessProvider"/>
<welcomeScreen implementation="com.intellij.ide.ui.laf.darcula.DarculaWelcomeScreenProvider"/>
+
<fileTypeFactory implementation="com.intellij.spi.SPIFileTypeFactory"/>
<lang.parserDefinition language="SPI" implementationClass="com.intellij.spi.parsing.SPIParserDefinition"/>
<lang.commenter language="SPI" implementationClass="com.intellij.spi.SPICommenter"/>
<annotator language="SPI" implementationClass="com.intellij.spi.SPIAnnotator"/>
+
+ <fileTypeFactory implementation="org.jetbrains.lang.manifest.ManifestFileTypeFactory"/>
+ <lang.parserDefinition language="Manifest" implementationClass="org.jetbrains.lang.manifest.parser.ManifestParserDefinition"/>
+ <lang.syntaxHighlighterFactory key="Manifest" implementationClass="org.jetbrains.lang.manifest.highlighting.ManifestSyntaxHighlighterFactory"/>
+ <annotator language="Manifest" implementationClass="org.jetbrains.lang.manifest.highlighting.HeaderAnnotator"/>
+ <lang.elementManipulator forClass="org.jetbrains.lang.manifest.psi.HeaderValuePart"
+ implementationClass="org.jetbrains.lang.manifest.psi.impl.HeaderValuePartManipulator"/>
+ <completion.contributor language="Manifest" implementationClass="org.jetbrains.lang.manifest.completion.ManifestCompletionContributor"/>
+ <manifest.parser.provider implementation="org.jetbrains.lang.manifest.header.impl.StandardManifestHeaderParsers"/>
+
+ <applicationService serviceImplementation="org.jetbrains.lang.manifest.header.HeaderParserRepository"/>
+
+ <localInspection language="Manifest" displayName="Missing Final New Line" groupName="Manifest"
+ enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.lang.manifest.highlighting.MissingFinalNewlineInspection"/>
+ <localInspection language="Manifest" displayName="Unknown or Misspelled Header Name" groupName="Manifest"
+ enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.lang.manifest.highlighting.MisspelledHeaderInspection"/>
+
<gotoDeclarationHandler implementation="com.intellij.codeInsight.navigation.actions.GotoLambdaParameterHandler"/>
<java.compilerOutputIndex implementation="com.intellij.compilerOutputIndex.impl.MethodsUsageIndex"/>
diff --git a/resources/src/idea/RichPlatformPlugin.xml b/resources/src/idea/RichPlatformPlugin.xml
index d0d63b1..c539ddb 100644
--- a/resources/src/idea/RichPlatformPlugin.xml
+++ b/resources/src/idea/RichPlatformPlugin.xml
@@ -78,6 +78,8 @@
<extensionPoint name="codeInsight.wordCompletionFilter" beanClass="com.intellij.lang.LanguageExtensionPoint"/>
+ <extensionPoint name="projectStructureConfigurableFilter" interface="com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurableFilter"/>
+ <extensionPoint name="projectStructureConfigurableAdder" interface="com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurableAdder"/>
<extensionPoint name="compiler" area="IDEA_PROJECT" interface="com.intellij.openapi.compiler.Compiler"/>
<extensionPoint name="compilerFactory" area="IDEA_PROJECT" interface="com.intellij.openapi.compiler.CompilerFactory"/>
diff --git a/xml/dom-impl/src/com/intellij/util/xml/EnumConverter.java b/xml/dom-impl/src/com/intellij/util/xml/EnumConverter.java
index 8dc15ed..0d86645 100644
--- a/xml/dom-impl/src/com/intellij/util/xml/EnumConverter.java
+++ b/xml/dom-impl/src/com/intellij/util/xml/EnumConverter.java
@@ -3,6 +3,7 @@
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlTag;
+import com.intellij.util.ReflectionCache;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.NotNull;
@@ -60,4 +61,8 @@
}
return Arrays.asList(myType.getEnumConstants());
}
+
+ public boolean isExhaustive() {
+ return !ReflectionCache.isAssignable(NonExhaustiveEnum.class, myType);
+ }
}
diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/GenericValueReferenceProvider.java b/xml/dom-impl/src/com/intellij/util/xml/impl/GenericValueReferenceProvider.java
index b457c9d..c36c2bf 100644
--- a/xml/dom-impl/src/com/intellij/util/xml/impl/GenericValueReferenceProvider.java
+++ b/xml/dom-impl/src/com/intellij/util/xml/impl/GenericValueReferenceProvider.java
@@ -24,6 +24,7 @@
import com.intellij.util.ProcessingContext;
import com.intellij.util.ReflectionCache;
import com.intellij.util.xml.*;
+import com.intellij.xml.util.XmlAttributeValueReferenceProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -86,6 +87,13 @@
}
}
}
+ if (references.length > 0) {
+ if (converter instanceof EnumConverter && !((EnumConverter)converter).isExhaustive()) {
+ // will be handled by core XML
+ return PsiReference.EMPTY_ARRAY;
+ }
+ context.put(XmlAttributeValueReferenceProvider.SUPPRESS, Boolean.TRUE);
+ }
return references;
}
diff --git a/xml/dom-openapi/src/com/intellij/util/xml/NonExhaustiveEnum.java b/xml/dom-openapi/src/com/intellij/util/xml/NonExhaustiveEnum.java
new file mode 100644
index 0000000..95b522e
--- /dev/null
+++ b/xml/dom-openapi/src/com/intellij/util/xml/NonExhaustiveEnum.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.util.xml;
+
+/**
+ * @author Dmitry Avdeev
+ * Date: 21.08.13
+ */
+public interface NonExhaustiveEnum {
+}
diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionData.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionData.java
index 00d6c1e..bf87f35 100644
--- a/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionData.java
+++ b/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionData.java
@@ -71,11 +71,14 @@
}
{
- final CompletionVariant variant = new CompletionVariant(createAttributeValueCompletionFilter());
- variant.includeScopeClass(XmlAttributeValue.class);
- variant.addCompletion(getAttributeValueGetter(), TailType.NONE);
- variant.addCompletionFilter(TrueFilter.INSTANCE, TailType.NONE);
- registerVariant(variant);
+ XmlAttributeValueGetter getter = getAttributeValueGetter();
+ if (getter != null) {
+ final CompletionVariant variant = new CompletionVariant(createAttributeValueCompletionFilter());
+ variant.includeScopeClass(XmlAttributeValue.class);
+ variant.addCompletion(getter, TailType.NONE);
+ variant.addCompletionFilter(TrueFilter.INSTANCE, TailType.NONE);
+ registerVariant(variant);
+ }
}
final ElementFilter entityCompletionFilter = createXmlEntityCompletionFilter();
diff --git a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/DependentNSReferenceQuickFixProvider.java b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/DependentNSReferenceQuickFixProvider.java
index 0fb6ef2..142e7df 100644
--- a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/DependentNSReferenceQuickFixProvider.java
+++ b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/DependentNSReferenceQuickFixProvider.java
@@ -12,7 +12,7 @@
*/
public class DependentNSReferenceQuickFixProvider extends UnresolvedReferenceQuickFixProvider<DependentNSReference> {
@Override
- public void registerFixes(DependentNSReference ref, QuickFixActionRegistrar registrar) {
+ public void registerFixes(@NotNull DependentNSReference ref, @NotNull QuickFixActionRegistrar registrar) {
registrar.register(new FetchExtResourceAction(ref.isForceFetchResultValid()));
registrar.register(new ManuallySetupExtResourceAction());
registrar.register(new IgnoreExtResourceAction());
diff --git a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferenceQuickFixProvider.java b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferenceQuickFixProvider.java
index 6b8bebd..eb3d558 100644
--- a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferenceQuickFixProvider.java
+++ b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferenceQuickFixProvider.java
@@ -27,7 +27,7 @@
*/
public class SchemaReferenceQuickFixProvider extends UnresolvedReferenceQuickFixProvider<SchemaReferencesProvider.TypeOrElementOrAttributeReference> {
@Override
- public void registerFixes(SchemaReferencesProvider.TypeOrElementOrAttributeReference ref, QuickFixActionRegistrar registrar) {
+ public void registerFixes(@NotNull SchemaReferencesProvider.TypeOrElementOrAttributeReference ref, @NotNull QuickFixActionRegistrar registrar) {
if (ref.getType() == SchemaReferencesProvider.TypeOrElementOrAttributeReference.ReferenceType.TypeReference) {
registrar.register(
new CreateXmlElementIntentionAction("xml.schema.create.complex.type.intention.name", SchemaReferencesProvider.COMPLEX_TYPE_TAG_NAME, ref)
diff --git a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/URLReferenceQuickFixProvider.java b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/URLReferenceQuickFixProvider.java
index 1c63a97..13bae7b 100644
--- a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/URLReferenceQuickFixProvider.java
+++ b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/URLReferenceQuickFixProvider.java
@@ -27,7 +27,7 @@
*/
public class URLReferenceQuickFixProvider extends UnresolvedReferenceQuickFixProvider<URLReference> {
@Override
- public void registerFixes(URLReference ref, QuickFixActionRegistrar registrar) {
+ public void registerFixes(@NotNull URLReference ref, @NotNull QuickFixActionRegistrar registrar) {
registrar.register(new FetchExtResourceAction());
registrar.register(new ManuallySetupExtResourceAction());
registrar.register(new IgnoreExtResourceAction());
diff --git a/xml/impl/src/com/intellij/xml/util/XmlAttributeValueReferenceProvider.java b/xml/impl/src/com/intellij/xml/util/XmlAttributeValueReferenceProvider.java
new file mode 100644
index 0000000..33d7201
--- /dev/null
+++ b/xml/impl/src/com/intellij/xml/util/XmlAttributeValueReferenceProvider.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.xml.util;
+
+import com.intellij.codeInsight.daemon.impl.analysis.XmlHighlightVisitor;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.PsiReferenceProvider;
+import com.intellij.psi.xml.XmlAttribute;
+import com.intellij.psi.xml.XmlAttributeValue;
+import com.intellij.util.ProcessingContext;
+import com.intellij.xml.XmlAttributeDescriptor;
+import com.intellij.xml.impl.BasicXmlAttributeDescriptor;
+import com.intellij.xml.impl.schema.XmlSchemaTagsProcessor;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Dmitry Avdeev
+ * Date: 15.08.13
+ */
+public class XmlAttributeValueReferenceProvider extends PsiReferenceProvider {
+
+ public final static Key<Boolean> SUPPRESS = Key.create("suppress attribute value references");
+
+ @NotNull
+ @Override
+ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
+
+ if (XmlSchemaTagsProcessor.PROCESSING_FLAG.get() != null || context.get(SUPPRESS) != null) {
+ return PsiReference.EMPTY_ARRAY;
+ }
+ XmlAttributeValue value = (XmlAttributeValue)element;
+ String unquotedValue = value.getValue();
+ if (unquotedValue == null || XmlHighlightVisitor.skipValidation(value) || !XmlUtil.isSimpleXmlAttributeValue(unquotedValue, value)) {
+ return PsiReference.EMPTY_ARRAY;
+ }
+ PsiElement parent = value.getParent();
+ if (parent instanceof XmlAttribute) {
+ final XmlAttributeDescriptor descriptor = ((XmlAttribute)parent).getDescriptor();
+ if (descriptor instanceof BasicXmlAttributeDescriptor &&
+ (descriptor.isFixed() || descriptor.isEnumerated() || unquotedValue.equals(descriptor.getDefaultValue()))) { // todo case insensitive
+ return ((BasicXmlAttributeDescriptor)descriptor).getValueReferences(value);
+ }
+ }
+ return PsiReference.EMPTY_ARRAY;
+ }
+}
diff --git a/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java b/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java
index 21d6abc..6fcd606 100644
--- a/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java
+++ b/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java
@@ -89,5 +89,6 @@
new XmlEncodingReferenceProvider());
registrar.registerReferenceProvider(xmlAttributeValue(), new XmlPrefixReferenceProvider());
+ registrar.registerReferenceProvider(xmlAttributeValue(), new XmlAttributeValueReferenceProvider(), PsiReferenceRegistrar.LOWER_PRIORITY);
}
}
diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngXmlAttributeDescriptor.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngXmlAttributeDescriptor.java
index 36760ce..db3d85e 100644
--- a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngXmlAttributeDescriptor.java
+++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngXmlAttributeDescriptor.java
@@ -17,14 +17,20 @@
package org.intellij.plugins.relaxNG.model.descriptors;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.text.DelimitedListProcessor;
+import com.intellij.psi.ElementManipulators;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiReference;
import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.xml.util.XmlAttributeValueReference;
import com.intellij.xml.impl.BasicXmlAttributeDescriptor;
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
@@ -201,4 +207,24 @@
private static String normalizeSpace(String value) {
return value.replaceAll("\\s+", " ").trim();
}
+
+ @Override
+ public PsiReference[] getValueReferences(final XmlAttributeValue value) {
+ String text = value.getValue();
+ if (text == null) return PsiReference.EMPTY_ARRAY;
+ final int offset = ElementManipulators.getValueTextRange(value).getStartOffset();
+ final List<PsiReference> list = new ArrayList<PsiReference>();
+ new DelimitedListProcessor("") {
+ @Override
+ protected boolean isDelimiter(char ch) {
+ return Character.isWhitespace(ch);
+ }
+
+ @Override
+ protected void processToken(int start, int end, boolean delimitersOnly) {
+ list.add(new XmlAttributeValueReference(value, TextRange.create(offset + start, offset + end), RngXmlAttributeDescriptor.this));
+ }
+ }.processText(text);
+ return list.toArray(new PsiReference[list.size()]);
+ }
}
\ No newline at end of file
diff --git a/xml/relaxng/testData/highlighting/attribute-choice-3.xml b/xml/relaxng/testData/highlighting/attribute-choice-3.xml
index c095d96..312c85d 100644
--- a/xml/relaxng/testData/highlighting/attribute-choice-3.xml
+++ b/xml/relaxng/testData/highlighting/attribute-choice-3.xml
@@ -1,2 +1,2 @@
-<attribute-choice xmlns="urn:test:simple.rng" type=<error>"c"</error>>
+<attribute-choice xmlns="urn:test:simple.rng" type="<error descr="Wrong attribute value">c</error>">
</attribute-choice>
\ No newline at end of file
diff --git a/xml/relaxng/testData/highlighting/fixed-attribute_2.xml b/xml/relaxng/testData/highlighting/fixed-attribute_2.xml
index a7a4b23..cf6c47a 100644
--- a/xml/relaxng/testData/highlighting/fixed-attribute_2.xml
+++ b/xml/relaxng/testData/highlighting/fixed-attribute_2.xml
@@ -1,2 +1,2 @@
-<fixed-attribute xmlns="urn:test:simple.rng" x=<error>"2.0"</error>>
+<fixed-attribute xmlns="urn:test:simple.rng" x="<error descr="Attribute should have fixed value 1.0">2.0</error>">
</fixed-attribute>
\ No newline at end of file
diff --git a/xml/relaxng/testData/highlighting/value-choice-2.xml b/xml/relaxng/testData/highlighting/value-choice-2.xml
index 8b026fe..fba9ef5 100644
--- a/xml/relaxng/testData/highlighting/value-choice-2.xml
+++ b/xml/relaxng/testData/highlighting/value-choice-2.xml
@@ -1,2 +1,2 @@
-<value-choice xmlns="urn:test:simple.rng" x=<error>"c"</error>>
+<value-choice xmlns="urn:test:simple.rng" x="<error descr="Wrong attribute value">c</error>">
</value-choice>
\ No newline at end of file
diff --git a/xml/tests/testData/xml/HighlightWhenNoNsSchemaLocation.xml b/xml/tests/testData/xml/HighlightWhenNoNsSchemaLocation.xml
index c9f2474..0ffab31 100644
--- a/xml/tests/testData/xml/HighlightWhenNoNsSchemaLocation.xml
+++ b/xml/tests/testData/xml/HighlightWhenNoNsSchemaLocation.xml
@@ -1,4 +1,4 @@
<build number="1" xsi:noNamespaceSchemaLocation="HighlightWhenNoNsSchemaLocation.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<statusInfo status="SUCCESS"/>
-<statusInfo status=<error>"SUCCESS2"</error>/>
+<statusInfo status="<error descr="Wrong attribute value">SUCCESS2</error>"/>
</build>
\ No newline at end of file
diff --git a/xml/xml-psi-impl/resources/messages/XmlErrorMessages.properties b/xml/xml-psi-impl/resources/messages/XmlErrorMessages.properties
index 2f90357..8ab43e2 100644
--- a/xml/xml-psi-impl/resources/messages/XmlErrorMessages.properties
+++ b/xml/xml-psi-impl/resources/messages/XmlErrorMessages.properties
@@ -20,8 +20,7 @@
invalid.id.reference=Invalid id reference
uri.is.not.registered=URI is not registered (Settings | Project Settings | Schemas and DTDs)
registered.resource.is.not.recognized=Resource registered by this uri is not recognized (Settings | Project Settings | Schemas and DTDs)
-# 0 - attr name, 1 - expected default value
-attribute.should.have.fixed.value=Attribute {0} should have fixed value {1}
+attribute.should.have.fixed.value=Attribute should have fixed value {0}
#quickfixes
insert.required.attribute.quickfix.text=Insert Required Attribute {0}
diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java
index 445a550..d6bbd3b 100644
--- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/html/dtd/HtmlAttributeDescriptorImpl.java
@@ -16,14 +16,16 @@
package com.intellij.psi.impl.source.html.dtd;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlElement;
import com.intellij.util.ArrayUtil;
import com.intellij.xml.XmlAttributeDescriptor;
+import com.intellij.xml.impl.BasicXmlAttributeDescriptor;
/**
* @author Maxim.Mossienko
*/
-public class HtmlAttributeDescriptorImpl implements XmlAttributeDescriptor {
+public class HtmlAttributeDescriptorImpl extends BasicXmlAttributeDescriptor {
private final XmlAttributeDescriptor delegate;
private final boolean myCaseSensitive;
@@ -90,4 +92,9 @@
public String toString() {
return delegate.toString();
}
+
+ @Override
+ protected PsiElement getEnumeratedValueDeclaration(XmlAttributeValue attributeValue, String value) {
+ return super.getEnumeratedValueDeclaration(attributeValue, myCaseSensitive ? value : value.toLowerCase());
+ }
}
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java
index 1aa72c3..83cf70f 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/BasicXmlAttributeDescriptor.java
@@ -24,40 +24,18 @@
*/
package com.intellij.xml.impl;
-import com.intellij.codeInsight.daemon.XmlErrorMessages;
+import com.intellij.openapi.util.Comparing;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlElement;
+import com.intellij.util.ArrayUtilRt;
+import com.intellij.xml.util.XmlAttributeValueReference;
import com.intellij.xml.XmlAttributeDescriptor;
-import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.Nullable;
public abstract class BasicXmlAttributeDescriptor implements XmlAttributeDescriptor {
public String validateValue(XmlElement context, String value) {
- if (isFixed()) {
- String defaultValue = getDefaultValue();
-
- if (defaultValue != null && !defaultValue.equals(value)) {
- return XmlErrorMessages.message("attribute.should.have.fixed.value", getName(), defaultValue);
- }
- }
-
- if (isEnumerated(context) && XmlUtil.isSimpleXmlAttributeValue(value, (XmlAttributeValue)context)) {
- String[] values = getEnumeratedValues(context);
- boolean valueWasFound = false;
-
- for (String enumValue : values) {
- if (enumValue.equals(value)) {
- valueWasFound = true;
- break;
- }
- }
-
- if (!valueWasFound) {
- return XmlErrorMessages.message("wrong.attribute.value");
- }
- }
-
return null;
}
@@ -78,4 +56,26 @@
public String toString() {
return getName();
}
+
+ public PsiElement getValueDeclaration(XmlAttributeValue attributeValue, String value) {
+ String defaultValue = getDefaultValue();
+ if (Comparing.equal(defaultValue, value)) {
+ return getDefaultValueDeclaration();
+ }
+ return isFixed() ? null : getEnumeratedValueDeclaration(attributeValue, value);
+ }
+
+ protected PsiElement getEnumeratedValueDeclaration(XmlAttributeValue attributeValue, String value) {
+ String[] values = getEnumeratedValues();
+ if (values == null || values.length == 0) return getDeclaration();
+ return ArrayUtilRt.find(values, value) != -1 ? getDeclaration() : null;
+ }
+
+ protected PsiElement getDefaultValueDeclaration() {
+ return getDeclaration();
+ }
+
+ public PsiReference[] getValueReferences(XmlAttributeValue value) {
+ return new PsiReference[] { new XmlAttributeValueReference(value, this)};
+ }
}
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java
index 195449b..2248f00 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java
@@ -15,22 +15,19 @@
*/
package com.intellij.xml.impl.schema;
+import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.meta.PsiWritableMetaData;
-import com.intellij.psi.xml.XmlElement;
-import com.intellij.psi.xml.XmlFile;
-import com.intellij.psi.xml.XmlTag;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.IncorrectOperationException;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.xml.*;
+import com.intellij.util.*;
import com.intellij.xml.XmlElementDescriptor;
import com.intellij.xml.impl.BasicXmlAttributeDescriptor;
import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.HashSet;
+import java.util.List;
/**
* @author Mike
@@ -38,6 +35,8 @@
public class XmlAttributeDescriptorImpl extends BasicXmlAttributeDescriptor implements PsiWritableMetaData {
private XmlTag myTag;
String myUse;
+ private boolean myExhaustiveEnum;
+
@NonNls
public static final String REQUIRED_ATTR_VALUE = "required";
@NonNls
@@ -115,18 +114,7 @@
}
public boolean isEnumerated(@Nullable XmlElement context) {
- final XmlElementDescriptorImpl elementDescriptor = (XmlElementDescriptorImpl)XmlUtil.findXmlDescriptorByType(
- myTag,
- context != null ?PsiTreeUtil.getContextOfType(context, XmlTag.class, true):null
- );
-
- if (elementDescriptor != null &&
- elementDescriptor.getType() instanceof ComplexTypeDescriptor) {
- final EnumerationData data = getEnumeratedValuesImpl(((ComplexTypeDescriptor)elementDescriptor.getType()).getDeclaration());
- return data != null && data.exaustive;
- }
-
- return false;
+ return processEnumeration(context, PairProcessor.TRUE);
}
public boolean isEnumerated() {
@@ -138,19 +126,27 @@
}
public String[] getEnumeratedValues(XmlElement context) {
- final XmlElementDescriptorImpl elementDescriptor = (XmlElementDescriptorImpl)XmlUtil.findXmlDescriptorByType(
- myTag,
- context != null ?PsiTreeUtil.getContextOfType(context, XmlTag.class, true):null
- );
+ final List<String> list = new SmartList<String>();
+ processEnumeration(context, new PairProcessor<PsiElement, String>() {
+ @Override
+ public boolean process(PsiElement element, String s) {
+ list.add(s);
+ return true;
+ }
+ });
+ String defaultValue = getDefaultValue();
+ if (defaultValue != null) {
+ list.add(defaultValue);
+ }
+ return ArrayUtil.toStringArray(list);
+ }
+
+ private boolean processEnumeration(XmlElement context, PairProcessor<PsiElement, String> processor) {
+ XmlTag contextTag = context != null ? PsiTreeUtil.getContextOfType(context, XmlTag.class, true) : null;
+ final XmlElementDescriptorImpl elementDescriptor = (XmlElementDescriptorImpl)XmlUtil.findXmlDescriptorByType(myTag, contextTag);
if (elementDescriptor!=null && elementDescriptor.getType() instanceof ComplexTypeDescriptor) {
- final EnumerationData data = getEnumeratedValuesImpl(((ComplexTypeDescriptor)elementDescriptor.getType()).getDeclaration());
- final String s = getDefaultValue();
-
- if (s != null && s.length() > 0 && data == null) {
- return new String[] {s};
- }
- return data != null? data.enumeratedValues:ArrayUtil.EMPTY_STRING_ARRAY;
+ return processEnumerationImpl(((ComplexTypeDescriptor)elementDescriptor.getType()).getDeclaration(), processor);
}
final String namespacePrefix = myTag.getNamespacePrefix();
@@ -159,35 +155,42 @@
);
if (type != null) {
- final EnumerationData data = getEnumeratedValuesImpl(type);
- return data != null? data.enumeratedValues:ArrayUtil.EMPTY_STRING_ARRAY;
+ return processEnumerationImpl(type, processor);
}
- return ArrayUtil.EMPTY_STRING_ARRAY;
+ return false;
}
- static class EnumerationData {
- final String[] enumeratedValues;
- final boolean exaustive;
-
- EnumerationData(@NotNull String[] _values, boolean _exaustive) {
- enumeratedValues = _values;
- exaustive = _exaustive;
- }
- }
-
- private static EnumerationData getEnumeratedValuesImpl(final XmlTag declaration) {
+ private boolean processEnumerationImpl(final XmlTag declaration, final PairProcessor<PsiElement, String> pairProcessor) {
if ("boolean".equals(declaration.getAttributeValue("name"))) {
- return new EnumerationData(new String[] {"true", "false"}, true);
+ XmlAttributeValue valueElement = declaration.getAttribute("name").getValueElement();
+ pairProcessor.process(valueElement, "true");
+ pairProcessor.process(valueElement, "false");
+ myExhaustiveEnum = true;
+ return true;
}
- final HashSet<String> variants = new HashSet<String>();
- final boolean exaustive = XmlUtil.collectEnumerationValues(declaration, variants);
-
- if (variants.size() > 0) {
- return new EnumerationData(ArrayUtil.toStringArray(variants), exaustive);
+ else {
+ final Ref<Boolean> found = new Ref<Boolean>(Boolean.FALSE);
+ myExhaustiveEnum = XmlUtil.processEnumerationValues(declaration, new Processor<XmlTag>() {
+ @Override
+ public boolean process(XmlTag tag) {
+ found.set(Boolean.TRUE);
+ XmlAttribute name = tag.getAttribute("value");
+ return name == null || pairProcessor.process(name.getValueElement(), name.getValue());
+ }
+ });
+ return found.get();
}
- return null;
+ }
+
+ @Override
+ public PsiElement getValueDeclaration(XmlAttributeValue attributeValue, String value) {
+ PsiElement declaration = super.getValueDeclaration(attributeValue, value);
+ if (declaration == null && !myExhaustiveEnum) {
+ return getDeclaration();
+ }
+ return declaration;
}
public String getName(PsiElement context) {
@@ -243,4 +246,20 @@
public void setName(String name) throws IncorrectOperationException {
NamedObjectDescriptor.setName(myTag, name);
}
+
+ @Override
+ protected PsiElement getEnumeratedValueDeclaration(XmlAttributeValue attributeValue, final String value) {
+ final Ref<PsiElement> result = new Ref<PsiElement>();
+ processEnumeration(myTag, new PairProcessor<PsiElement, String>() {
+ @Override
+ public boolean process(PsiElement element, String s) {
+ if (value.equals(s)) {
+ result.set(element);
+ return false;
+ }
+ return true;
+ }
+ });
+ return result.get();
+ }
}
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java
index 8b4c20a..4e5e37e 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java
@@ -757,7 +757,7 @@
return true;
}
- protected static boolean equalsToSchemaName(XmlTag tag, @NonNls String schemaName) {
+ protected static boolean equalsToSchemaName(@NotNull XmlTag tag, @NonNls String schemaName) {
return schemaName.equals(tag.getLocalName()) && checkSchemaNamespace(tag);
}
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlSchemaTagsProcessor.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlSchemaTagsProcessor.java
index b884ced..98cb0b4 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlSchemaTagsProcessor.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlSchemaTagsProcessor.java
@@ -31,6 +31,8 @@
*/
public abstract class XmlSchemaTagsProcessor {
+ public final static ThreadLocal<Boolean> PROCESSING_FLAG = new ThreadLocal<Boolean>();
+
private final Set<XmlTag> myVisited = new HashSet<XmlTag>();
protected final XmlNSDescriptorImpl myNsDescriptor;
private final String[] myTagsToIgnore;
@@ -41,10 +43,16 @@
}
public final void startProcessing(XmlTag tag) {
- processTag(tag, null);
+ try {
+ PROCESSING_FLAG.set(Boolean.TRUE);
+ processTag(tag, null);
+ }
+ finally {
+ PROCESSING_FLAG.set(null);
+ }
}
- public void processTag(XmlTag tag, @Nullable XmlTag context) {
+ private void processTag(XmlTag tag, @Nullable XmlTag context) {
if (myVisited.contains(tag)) return;
myVisited.add(tag);
@@ -80,6 +88,7 @@
if (ref == null) return;
XmlTag group;
XmlTag parentTag = tag.getParentTag();
+ assert parentTag != null;
if (XmlNSDescriptorImpl.equalsToSchemaName(parentTag, "attributeGroup") &&
ref.equals(parentTag.getAttributeValue("name"))) {
group = resolveTagReference(tag.getAttribute("ref"));
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/util/XmlAttributeValueReference.java b/xml/xml-psi-impl/src/com/intellij/xml/util/XmlAttributeValueReference.java
new file mode 100644
index 0000000..75a604b
--- /dev/null
+++ b/xml/xml-psi-impl/src/com/intellij/xml/util/XmlAttributeValueReference.java
@@ -0,0 +1,75 @@
+/*
+ * 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.xml.util;
+
+import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider;
+import com.intellij.codeInsight.daemon.XmlErrorMessages;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReferenceBase;
+import com.intellij.psi.xml.XmlAttributeValue;
+import com.intellij.util.ArrayUtil;
+import com.intellij.xml.XmlAttributeDescriptor;
+import com.intellij.xml.impl.BasicXmlAttributeDescriptor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+* @author Dmitry Avdeev
+* Date: 16.08.13
+*/
+public class XmlAttributeValueReference extends PsiReferenceBase<XmlAttributeValue> implements EmptyResolveMessageProvider {
+ private final XmlAttributeDescriptor myDescriptor;
+
+ public XmlAttributeValueReference(XmlAttributeValue value, XmlAttributeDescriptor descriptor) {
+ super(value);
+ myDescriptor = descriptor;
+ }
+
+ public XmlAttributeValueReference(XmlAttributeValue element,
+ TextRange range,
+ XmlAttributeDescriptor descriptor) {
+ super(element, range);
+ myDescriptor = descriptor;
+ }
+
+ @Nullable
+ @Override
+ public PsiElement resolve() {
+ return ((BasicXmlAttributeDescriptor)myDescriptor).getValueDeclaration(getElement(), getValue());
+ }
+
+ @NotNull
+ @Override
+ public Object[] getVariants() {
+ if (myDescriptor.isFixed()) {
+ String defaultValue = myDescriptor.getDefaultValue();
+ return defaultValue == null ? ArrayUtil.EMPTY_OBJECT_ARRAY : new Object[] {defaultValue};
+ }
+ else {
+ String[] values = myDescriptor.getEnumeratedValues();
+ return values == null ? ArrayUtil.EMPTY_OBJECT_ARRAY : values;
+ }
+ }
+
+ @NotNull
+ @Override
+ public String getUnresolvedMessagePattern() {
+ return myDescriptor.isFixed()
+ ? XmlErrorMessages.message("attribute.should.have.fixed.value", myDescriptor.getDefaultValue())
+ : XmlErrorMessages.message("wrong.attribute.value");
+ }
+}
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/util/XmlUtil.java b/xml/xml-psi-impl/src/com/intellij/xml/util/XmlUtil.java
index ee38a7e..e8bb8f4 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/util/XmlUtil.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/util/XmlUtil.java
@@ -933,26 +933,33 @@
});
}
+ /**
+ * @return true if enumeration is exhaustive
+ */
public static boolean processEnumerationValues(final XmlTag element, final Processor<XmlTag> tagProcessor) {
- boolean exaustiveEnum = true;
+ boolean exhaustiveEnum = true;
for (final XmlTag tag : element.getSubTags()) {
@NonNls final String localName = tag.getLocalName();
if (localName.equals(ENUMERATION_TAG_NAME)) {
final String attributeValue = tag.getAttributeValue(VALUE_ATTR_NAME);
- if (attributeValue != null) tagProcessor.process(tag);
+ if (attributeValue != null) {
+ if (!tagProcessor.process(tag)) {
+ return exhaustiveEnum;
+ }
+ }
}
else if (localName.equals("union")) {
- exaustiveEnum = false;
+ exhaustiveEnum = false;
processEnumerationValues(tag, tagProcessor);
}
else if (!localName.equals("annotation")) {
// don't go into annotation
- exaustiveEnum &= processEnumerationValues(tag, tagProcessor);
+ exhaustiveEnum &= processEnumerationValues(tag, tagProcessor);
}
}
- return exaustiveEnum;
+ return exhaustiveEnum;
}
/**
@@ -1063,12 +1070,15 @@
return new Pair<XmlTagChild, XmlTagChild>(first, last);
}
- public static boolean isSimpleXmlAttributeValue(final String unquotedValue, final XmlAttributeValue context) {
+ public static boolean isSimpleXmlAttributeValue(@NotNull final String unquotedValue, final XmlAttributeValue context) {
for (int i = 0; i < unquotedValue.length(); ++i) {
final char ch = unquotedValue.charAt(i);
if (!Character.isJavaIdentifierPart(ch) && ch != ':' && ch != '-') {
final XmlFile file = PsiTreeUtil.getParentOfType(context, XmlFile.class);
- return file != null && !tagFromTemplateFramework(file.getRootTag());
+ if (file != null) {
+ XmlTag tag = file.getRootTag();
+ return tag != null && !tagFromTemplateFramework(tag);
+ }
}
}
return true;