mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote branch 'origin/master'
This commit is contained in:
Generated
+2
-2
@@ -1,11 +1,11 @@
|
||||
<component name="libraryTable">
|
||||
<library name="winp">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/winp-1.16-patched.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/winp-1.17-patched.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/src/winp-1.16-patched-src.zip!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/src/winp-1.17-patched-src.zip!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -106,7 +106,7 @@ def layoutAll(Map args, String home, String out, Paths _paths = null, buildJps =
|
||||
layouts.layout_core_upsource(home, paths.artifacts_core_upsource)
|
||||
notifyArtifactBuilt(paths.artifacts_core_upsource)
|
||||
if (buildJps) {
|
||||
layouts.layout_jps(home, paths.artifacts_jps)
|
||||
layouts.layoutCommunityJps(home, paths.artifacts_jps)
|
||||
notifyArtifactBuilt(paths.artifacts_jps)
|
||||
}
|
||||
|
||||
|
||||
+29
-13
@@ -23,11 +23,6 @@ target('default': "Developers update") {
|
||||
ant.delete(dir: patchedDescriptorDir)
|
||||
}
|
||||
|
||||
target('build-jps': 'Build JPS standalone distribution') {
|
||||
println("Building jps standalone distribution")
|
||||
layout_jps("$home/build/lib/jps")
|
||||
}
|
||||
|
||||
String appInfoFileName() {
|
||||
return "idea/IdeaApplicationInfo.xml"
|
||||
}
|
||||
@@ -183,11 +178,13 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir
|
||||
|
||||
layoutCommunityPlugins(home)
|
||||
|
||||
layoutPlugin("javaFX") {
|
||||
dir("lib") {
|
||||
jar("javaFX.jar") {
|
||||
module("javaFX")
|
||||
module("javaFX-CE")
|
||||
dir("plugins") {
|
||||
dir("javaFX") {
|
||||
dir("lib") {
|
||||
jar("javaFX.jar") {
|
||||
module("javaFX")
|
||||
module("javaFX-CE")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -569,7 +566,7 @@ def reorder(String home, String targetDirectory) {
|
||||
}
|
||||
}
|
||||
|
||||
def layout_jps(String home, String target) {
|
||||
def layoutCommunityJps(String home, String target) {
|
||||
layout(target) {
|
||||
jar("util.jar") {
|
||||
module("annotations")
|
||||
@@ -596,9 +593,27 @@ def layout_jps(String home, String target) {
|
||||
jar("groovy_rt.jar") {
|
||||
module("groovy_rt")
|
||||
}
|
||||
jar("ui-designer-jps-plugin.jar") {
|
||||
module("ui-designer-jps-plugin")
|
||||
jar("ui-designer-jps-plugin.jar") { module("ui-designer-jps-plugin") }
|
||||
|
||||
jar("android-jps-plugin.jar") {
|
||||
module("android-jps-plugin")
|
||||
module("android-common")
|
||||
module("android-rt")
|
||||
}
|
||||
fileset(dir: "${home}/plugins/android/lib") {
|
||||
include(name: "**/*.jar")
|
||||
exclude(name: "**/ddmlib_1.jar")
|
||||
}
|
||||
|
||||
jar("maven-jps-plugin.jar") { module("maven-jps-plugin") }
|
||||
fileset(dir: "$home/plugins/maven/maven3-server-impl/lib/maven3/lib") {include(name: "plexus-utils-*.jar")}
|
||||
|
||||
jar("eclipse-jps-plugin.jar") {
|
||||
module("common-eclipse-util")
|
||||
module("eclipse-jps-plugin")
|
||||
}
|
||||
jar("devkit-jps-plugin.jar") { module("devkit-jps-plugin") }
|
||||
jar("intellilang-jps-plugin.jar") { module("intellilang-jps-plugin") }
|
||||
fileset(dir: "$home/lib") {
|
||||
include(name: "jdom.jar")
|
||||
include(name: "jna.jar")
|
||||
@@ -606,6 +621,7 @@ def layout_jps(String home, String target) {
|
||||
include(name: "asm4-all.jar")
|
||||
include(name: "nanoxml-*.jar")
|
||||
include(name: "protobuf-*.jar")
|
||||
include(name: "cli-parser-*.jar")
|
||||
include(name: "optimizedFileManager.jar")
|
||||
include(name: "log4j.jar")
|
||||
include(name: "jgoodies-forms.jar")
|
||||
|
||||
@@ -235,7 +235,7 @@ libraryLicense(name: "TestNG", version: "5.7 snapshot", license: "Apache 2.0", u
|
||||
libraryLicense(name: "Trilead SSH", libraryName: "trilead-ssh2", version: "build 213", license: "BSD style (see LICENSE.txt in trilead.jar)", url: "http://www.trilead.com/SSH_Library/")
|
||||
libraryLicense(name: "Trove4j", version: "1.1 (with patches by JetBrains)", license: "LGPL", url: "http://trove4j.sourceforge.net/", licenseUrl: "http://trove4j.sourceforge.net/html/license.html")
|
||||
libraryLicense(name: "Velocity", version: "1.7", license: "Apache 2.0", url: "http://velocity.apache.org/", licenseUrl: "http://velocity.apache.org/index.html")
|
||||
libraryLicense(name: "winp", version: "1.16 (patched)", license: "MIT", url: "http://java.net/projects/winp", licenseUrl: "http://opensource.org/licenses/mit-license.php")
|
||||
libraryLicense(name: "winp", version: "1.17 (patched)", license: "MIT", url: "http://java.net/projects/winp", licenseUrl: "http://opensource.org/licenses/mit-license.php")
|
||||
libraryLicense(name: "Xalan", libraryName:"Xalan-2.7.1", version: "2.7.1", license: "Apache 2.0", url: "http://xml.apache.org/xalan-j/", licenseUrl: "http://xml.apache.org/xalan-j/")
|
||||
libraryLicense(name: "Xerces", version: "2.9.1", license: "Apache 2.0", url: "http://xerces.apache.org/xerces2-j/", licenseUrl: "http://xerces.apache.org/xerces2-j/")
|
||||
libraryLicense(name: "XML Commons (xml-apis.jar, resolver.jar)", version: "", license: "Apache 2.0, W3C Software License , public domain", url: "http://xml.apache.org/commons/", licenseUrl: "http://xml.apache.org/commons/licenses.html")
|
||||
@@ -254,6 +254,7 @@ libraryLicense(name: "proxy-vole", libraryName: "proxy-vole", version: "20120920
|
||||
libraryLicense(name: "Rhino JavaScript Engine", libraryName: "rhino-js-1_7R4", version: "1.7R4", license: "MPL 1.1", url: "http://www.mozilla.org/rhino/", licenseUrl: "http://www.mozilla.org/MPL/MPL-1.1.html")
|
||||
libraryLicense(name: "asm-4.0-all", libraryName: "asm-4.0-all", version: "4.0", attachedTo: "ByteCodeViewer", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
|
||||
libraryLicense(name: "jsr305", libraryName: "jsr305", version: "snapshot", license: "BSD", url: "http://code.google.com/p/jsr-305/", licenseUrl: "http://code.google.com/p/jsr-305/source/browse/trunk/ri/LICENSE")
|
||||
libraryLicense(name: "jzlib", libraryName: "jzlib", version: "1.1.1", license: "BSD", url: "http://www.jcraft.com/jzlib/", licenseUrl: "http://www.jcraft.com/jzlib/LICENSE.txt")
|
||||
jetbrainsLibrary("JPS")
|
||||
jetbrainsLibrary("Maven Embedder")
|
||||
jetbrainsLibrary("tcServiceMessages")
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<option name="EDITOR_FONT_SIZE" value="12" />
|
||||
<option name="EDITOR_FONT_NAME" value="Menlo" />
|
||||
<colors>
|
||||
<option name="ADDED_LINES_COLOR" value="d6822" />
|
||||
<option name="ADDED_LINES_COLOR" value="295622" />
|
||||
<option name="ANNOTATIONS_COLOR" value="8b999f" />
|
||||
<option name="CARET_COLOR" value="bbbbbb" />
|
||||
<option name="CARET_ROW_COLOR" value="323232" />
|
||||
@@ -26,19 +26,19 @@
|
||||
<option name="FILESTATUS_changelistConflict" value="d5756c" />
|
||||
<option name="FILESTATUS_modifiedOutside" value="6897bb" />
|
||||
<option name="GUTTER_BACKGROUND" value="313335" />
|
||||
<option name="INDENT_GUIDE" value="4d4d4d" />
|
||||
<option name="INDENT_GUIDE" value="373737" />
|
||||
<option name="LINE_NUMBERS_COLOR" value="888888" />
|
||||
<option name="METHOD_SEPARATORS_COLOR" value="4d4d4d" />
|
||||
<option name="MODIFIED_LINES_COLOR" value="7180" />
|
||||
<option name="MODIFIED_LINES_COLOR" value="415f69" />
|
||||
<option name="NOTIFICATION_BACKGROUND" value="5c5c42" />
|
||||
<option name="READONLY_FRAGMENT_BACKGROUND" value="" />
|
||||
<option name="RECURSIVE_CALL_ATTRIBUTES" value="574300" />
|
||||
<option name="REMOTE_HOST_MAPPED_BACKGROUND_KEY" value="164716" />
|
||||
<option name="RIGHT_MARGIN_COLOR" value="4d4d4d" />
|
||||
<option name="SELECTED_TEARLINE_COLOR" value="ffffff" />
|
||||
<option name="SELECTED_INDENT_GUIDE" value="505050" />
|
||||
<option name="SELECTED_TEARLINE_COLOR" value="787878" />
|
||||
<option name="SELECTION_BACKGROUND" value="214283" />
|
||||
<option name="SELECTION_FOREGROUND" value="" />
|
||||
<option name="TEARLINE_COLOR" value="909090" />
|
||||
<option name="TEARLINE_COLOR" value="555555" />
|
||||
<option name="WHITESPACES" value="404040" />
|
||||
</colors>
|
||||
<attributes>
|
||||
@@ -415,26 +415,26 @@
|
||||
</option>
|
||||
<option name="DIFF_CONFLICT">
|
||||
<value>
|
||||
<option name="BACKGROUND" value="763c3d" />
|
||||
<option name="ERROR_STRIPE_COLOR" value="763c3d" />
|
||||
<option name="BACKGROUND" value="45302b" />
|
||||
<option name="ERROR_STRIPE_COLOR" value="8f5247" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="DIFF_DELETED">
|
||||
<value>
|
||||
<option name="BACKGROUND" value="0" />
|
||||
<option name="ERROR_STRIPE_COLOR" value="0" />
|
||||
<option name="BACKGROUND" value="484a4a" />
|
||||
<option name="ERROR_STRIPE_COLOR" value="656e76" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="DIFF_INSERTED">
|
||||
<value>
|
||||
<option name="BACKGROUND" value="365d40" />
|
||||
<option name="ERROR_STRIPE_COLOR" value="365d40" />
|
||||
<option name="BACKGROUND" value="294436" />
|
||||
<option name="ERROR_STRIPE_COLOR" value="447152" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="DIFF_MODIFIED">
|
||||
<value>
|
||||
<option name="BACKGROUND" value="337184" />
|
||||
<option name="ERROR_STRIPE_COLOR" value="326174" />
|
||||
<option name="BACKGROUND" value="385570" />
|
||||
<option name="ERROR_STRIPE_COLOR" value="43698d" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="DOC_COMMENT_TAG_VALUE">
|
||||
@@ -1143,192 +1143,6 @@
|
||||
<option name="FONT_TYPE" value="1" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_ATTR_ACCESSOR_CALL">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="cc7833" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_ATTR_READER_CALL">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="cc7833" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_ATTR_WRITER_CALL">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="cc7833" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_BACK_REF">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="0" />
|
||||
<option name="FONT_TYPE" value="1" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_BAD_CHARACTER">
|
||||
<value>
|
||||
<option name="EFFECT_COLOR" value="ff0000" />
|
||||
<option name="EFFECT_TYPE" value="2" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_COMMA">
|
||||
<value />
|
||||
</option>
|
||||
<option name="RUBY_COMMENT">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="bc9458" />
|
||||
<option name="FONT_TYPE" value="2" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_CONSTANT">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="da4939" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_CONSTANT_DEF_ID">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="9f0e9b" />
|
||||
<option name="FONT_TYPE" value="3" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_CVAR">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="d0d0ff" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_ESCAPE_SEQUENCE">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="519f50" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_EXPR_IN_STRING">
|
||||
<value />
|
||||
</option>
|
||||
<option name="RUBY_GVAR">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="d0d0ff" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_HASH_ASSOC">
|
||||
<value />
|
||||
</option>
|
||||
<option name="RUBY_HEREDOC_CONTENT">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="a5c261" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_HEREDOC_ID">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="a5c261" />
|
||||
<option name="EFFECT_TYPE" value="1" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_IMPORT_CALL">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="cc7833" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_INTERPOLATED_STRING">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="52a12e" />
|
||||
<option name="FONT_TYPE" value="1" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_INVALID_ESCAPE_SEQUENCE">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="519f50" />
|
||||
<option name="EFFECT_COLOR" value="ff0000" />
|
||||
<option name="EFFECT_TYPE" value="2" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_IVAR">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="d0d0ff" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_KEYWORD">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="cc7833" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_LINE_CONTINUATION">
|
||||
<value />
|
||||
</option>
|
||||
<option name="RUBY_LOCAL_VAR_ID">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="78b4" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_METHOD_NAME">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="ffc66d" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_NTH_REF">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="d0d0ff" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_NUMBER">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="a5c261" />
|
||||
<option name="EFFECT_TYPE" value="1" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_OPERATION_SIGN">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="cc7833" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_PARAMETER_ID">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="c37522" />
|
||||
<option name="EFFECT_TYPE" value="2" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_PRIVATE_CALL">
|
||||
<value>
|
||||
<option name="FONT_TYPE" value="1" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_PROTECTED_CALL">
|
||||
<value>
|
||||
<option name="FONT_TYPE" value="1" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_PUBLIC_CALL">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="cc7833" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_REGEXP">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="a5c261" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_REQUIRE_ARG_CALL">
|
||||
<value>
|
||||
<option name="FONT_TYPE" value="3" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_REQUIRE_CALL">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="cc7833" />
|
||||
<option name="EFFECT_TYPE" value="2" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_SEMICOLON">
|
||||
<value />
|
||||
</option>
|
||||
<option name="RUBY_SPECIFIC_CALL">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="da4939" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RUBY_SYMBOL">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="6e9cbe" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="SASS_ATTRIBUTE">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="6d9cbe" />
|
||||
@@ -1704,7 +1518,7 @@
|
||||
</option>
|
||||
<option name="TODO_DEFAULT_ATTRIBUTES">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="bc9458" />
|
||||
<option name="FOREGROUND" value="a8c023" />
|
||||
<option name="FONT_TYPE" value="2" />
|
||||
</value>
|
||||
</option>
|
||||
@@ -1801,7 +1615,7 @@
|
||||
</option>
|
||||
<option name="XML_ATTRIBUTE_NAME">
|
||||
<value>
|
||||
<option name="FOREGROUND" value="d0d0ff" />
|
||||
<option name="FOREGROUND" value="bababa" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="XML_ATTRIBUTE_VALUE">
|
||||
|
||||
+3
-2
@@ -73,13 +73,14 @@ public final class CompiledClassPropertiesProvider implements PropertiesProvider
|
||||
|
||||
final Method readMethod = descriptor.getReadMethod();
|
||||
final Method writeMethod = descriptor.getWriteMethod();
|
||||
if (writeMethod == null || readMethod == null) {
|
||||
final Class propertyType = descriptor.getPropertyType();
|
||||
if (writeMethod == null || readMethod == null || propertyType == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String name = descriptor.getName();
|
||||
|
||||
final LwIntrospectedProperty property = propertyFromClass(descriptor.getPropertyType(), name);
|
||||
final LwIntrospectedProperty property = propertyFromClass(propertyType, name);
|
||||
|
||||
if (property != null) {
|
||||
property.setDeclaringClassName(descriptor.getReadMethod().getDeclaringClass().getName());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.compiler.options.CompilerUIConfigurable">
|
||||
<grid id="1663f" binding="myPanel" layout-manager="GridLayoutManager" row-count="10" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="1663f" binding="myPanel" layout-manager="GridLayoutManager" row-count="11" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="28" y="24" width="883" height="379"/>
|
||||
@@ -10,7 +10,7 @@
|
||||
<children>
|
||||
<vspacer id="67edf">
|
||||
<constraints>
|
||||
<grid row="9" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="10" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<grid id="b341d" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="1">
|
||||
@@ -95,7 +95,7 @@
|
||||
</component>
|
||||
<component id="17126" class="javax.swing.JLabel" binding="myHeapSizeLabel">
|
||||
<constraints>
|
||||
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
|
||||
<grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Compiler process heap size (Mbytes):"/>
|
||||
@@ -103,7 +103,7 @@
|
||||
</component>
|
||||
<component id="a28b8" class="javax.swing.JTextField" binding="myHeapSizeField">
|
||||
<constraints>
|
||||
<grid row="7" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false">
|
||||
<grid row="8" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="50" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
@@ -111,7 +111,7 @@
|
||||
</component>
|
||||
<component id="5b86a" class="javax.swing.JLabel" binding="myVMOptionsLabel">
|
||||
<constraints>
|
||||
<grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
|
||||
<grid row="9" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Additional compiler process VM options:"/>
|
||||
@@ -119,7 +119,7 @@
|
||||
</component>
|
||||
<component id="b5547" class="javax.swing.JTextField" binding="myVMOptionsField">
|
||||
<constraints>
|
||||
<grid row="8" 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="9" 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>
|
||||
@@ -149,6 +149,14 @@
|
||||
<text value="(only works while not running / debugging)"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="4b44" class="javax.swing.JCheckBox" binding="myCbRebuildOnDependencyChange" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Rebuild module on dependency change"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
||||
@@ -55,6 +55,7 @@ public class CompilerUIConfigurable implements SearchableConfigurable, Configura
|
||||
private JTextField myVMOptionsField;
|
||||
private JLabel myHeapSizeLabel;
|
||||
private JLabel myVMOptionsLabel;
|
||||
private JCheckBox myCbRebuildOnDependencyChange;
|
||||
|
||||
public CompilerUIConfigurable(final Project project) {
|
||||
myProject = project;
|
||||
@@ -84,6 +85,7 @@ public class CompilerUIConfigurable implements SearchableConfigurable, Configura
|
||||
myCbUseExternalBuild.setSelected(workspaceConfiguration.USE_COMPILE_SERVER);
|
||||
myCbEnableAutomake.setSelected(workspaceConfiguration.MAKE_PROJECT_ON_SAVE);
|
||||
myCbParallelCompilation.setSelected(workspaceConfiguration.PARALLEL_COMPILATION);
|
||||
myCbRebuildOnDependencyChange.setSelected(workspaceConfiguration.REBUILD_ON_DEPENDENCY_CHANGE);
|
||||
myHeapSizeField.setText(String.valueOf(workspaceConfiguration.COMPILER_PROCESS_HEAP_SIZE));
|
||||
final String options = workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS;
|
||||
myVMOptionsField.setText(options == null? "" : options.trim());
|
||||
@@ -115,6 +117,7 @@ public class CompilerUIConfigurable implements SearchableConfigurable, Configura
|
||||
workspaceConfiguration.USE_COMPILE_SERVER = myCbUseExternalBuild.isSelected();
|
||||
workspaceConfiguration.MAKE_PROJECT_ON_SAVE = myCbEnableAutomake.isSelected();
|
||||
workspaceConfiguration.PARALLEL_COMPILATION = myCbParallelCompilation.isSelected();
|
||||
workspaceConfiguration.REBUILD_ON_DEPENDENCY_CHANGE = myCbRebuildOnDependencyChange.isSelected();
|
||||
try {
|
||||
workspaceConfiguration.COMPILER_PROCESS_HEAP_SIZE = Integer.parseInt(myHeapSizeField.getText().trim());
|
||||
}
|
||||
@@ -173,6 +176,7 @@ public class CompilerUIConfigurable implements SearchableConfigurable, Configura
|
||||
isModified |= ComparingUtils.isModified(myCbUseExternalBuild, workspaceConfiguration.USE_COMPILE_SERVER);
|
||||
isModified |= ComparingUtils.isModified(myCbEnableAutomake, workspaceConfiguration.MAKE_PROJECT_ON_SAVE);
|
||||
isModified |= ComparingUtils.isModified(myCbParallelCompilation, workspaceConfiguration.PARALLEL_COMPILATION);
|
||||
isModified |= ComparingUtils.isModified(myCbRebuildOnDependencyChange, workspaceConfiguration.REBUILD_ON_DEPENDENCY_CHANGE);
|
||||
isModified |= ComparingUtils.isModified(myHeapSizeField, workspaceConfiguration.COMPILER_PROCESS_HEAP_SIZE);
|
||||
isModified |= ComparingUtils.isModified(myVMOptionsField, workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS);
|
||||
|
||||
@@ -211,6 +215,7 @@ public class CompilerUIConfigurable implements SearchableConfigurable, Configura
|
||||
private void updateExternalMakeOptionControls(boolean enabled) {
|
||||
myCbEnableAutomake.setEnabled(enabled);
|
||||
myCbParallelCompilation.setEnabled(enabled);
|
||||
myCbRebuildOnDependencyChange.setEnabled(enabled);
|
||||
myHeapSizeField.setEnabled(enabled);
|
||||
myVMOptionsField.setEnabled(enabled);
|
||||
myHeapSizeLabel.setEnabled(enabled);
|
||||
|
||||
@@ -41,7 +41,6 @@ import com.intellij.openapi.project.DumbModeAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.project.ProjectManagerListener;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -210,20 +209,6 @@ public class CompilerTask extends Task.Backgroundable {
|
||||
closeUI();
|
||||
}
|
||||
stopAppIconProgress();
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
if (myProject == null || myProject.isDisposed())
|
||||
return;
|
||||
NotificationInfo notificationInfo = getNotificationInfo();
|
||||
if (notificationInfo != null && !myMessagesAutoActivated && (myErrorCount > 0 || (myWarningCount > 0 && !ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings()))) {
|
||||
MessageType messageType = myErrorCount > 0 ? MessageType.ERROR : myWarningCount > 0 ? MessageType.WARNING : MessageType.INFO;
|
||||
ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.MESSAGES_WINDOW, messageType,
|
||||
getNotificationInfo().getNotificationText(), null, null);
|
||||
}
|
||||
}
|
||||
};
|
||||
ApplicationManager.getApplication().invokeLater(runnable);
|
||||
}
|
||||
|
||||
private void stopAppIconProgress() {
|
||||
@@ -334,6 +319,7 @@ public class CompilerTask extends Task.Backgroundable {
|
||||
(CompilerMessageCategory.WARNING.equals(category) && !ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings())
|
||||
);
|
||||
if (shouldAutoActivate) {
|
||||
myMessagesAutoActivated = true;
|
||||
activateMessageView();
|
||||
}
|
||||
}
|
||||
@@ -458,7 +444,7 @@ public class CompilerTask extends Task.Backgroundable {
|
||||
if (myErrorTreeView != null) {
|
||||
final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.MESSAGES_WINDOW);
|
||||
if (tw != null) {
|
||||
myMessagesAutoActivated = tw.activate(null, false, false, false);
|
||||
tw.activate(null, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,10 @@ import com.intellij.execution.process.*;
|
||||
import com.intellij.execution.ui.RunContentDescriptor;
|
||||
import com.intellij.ide.PowerSaveMode;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -123,7 +126,8 @@ public class BuildManager implements ApplicationComponent{
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.server.BuildManager");
|
||||
private static final String COMPILER_PROCESS_JDK_PROPERTY = "compiler.process.jdk";
|
||||
private static final String SYSTEM_ROOT = "compile-server";
|
||||
public static final String SYSTEM_ROOT = "compile-server";
|
||||
public static final String TEMP_DIR_NAME = "_temp_";
|
||||
private static final String LOGGER_CONFIG = "log.xml";
|
||||
private static final String DEFAULT_LOGGER_CONFIG = "defaultLogConfig.xml";
|
||||
private static final int MAKE_TRIGGER_DELAY = 300 /*300 ms*/;
|
||||
@@ -211,6 +215,7 @@ public class BuildManager implements ApplicationComponent{
|
||||
private final BuildMessageDispatcher myMessageDispatcher = new BuildMessageDispatcher();
|
||||
private volatile int myListenPort = -1;
|
||||
private volatile CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings myGlobals;
|
||||
private int myGlobalsStamp = -1;
|
||||
@Nullable
|
||||
private final Charset mySystemCharset;
|
||||
|
||||
@@ -533,11 +538,7 @@ public class BuildManager implements ApplicationComponent{
|
||||
return;
|
||||
}
|
||||
|
||||
CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = myGlobals;
|
||||
if (globals == null) {
|
||||
globals = buildGlobalSettings();
|
||||
myGlobals = globals;
|
||||
}
|
||||
final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = buildGlobalSettings();
|
||||
CmdlineRemoteProto.Message.ControllerMessage.FSEvent currentFSChanges;
|
||||
final SequentialTaskExecutor projectTaskQueue;
|
||||
synchronized (myProjectDataMap) {
|
||||
@@ -686,14 +687,22 @@ public class BuildManager implements ApplicationComponent{
|
||||
return "com.intellij.compiler.server.BuildManager";
|
||||
}
|
||||
|
||||
private static CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings buildGlobalSettings() {
|
||||
private CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings buildGlobalSettings() {
|
||||
final PathMacrosImpl pathVars = PathMacrosImpl.getInstanceEx();
|
||||
|
||||
final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings cached = myGlobals;
|
||||
if (cached != null && myGlobalsStamp == pathVars.getModificationStamp()) {
|
||||
return cached;
|
||||
}
|
||||
myGlobals = null; // ensure the cache is cleared and stamp is current
|
||||
myGlobalsStamp = pathVars.getModificationStamp();
|
||||
|
||||
final Map<String, String> data = new HashMap<String, String>();
|
||||
|
||||
for (Map.Entry<String, String> entry : PathMacrosImpl.getGlobalSystemMacros().entrySet()) {
|
||||
data.put(entry.getKey(), FileUtil.toSystemIndependentName(entry.getValue()));
|
||||
}
|
||||
|
||||
final PathMacros pathVars = PathMacros.getInstance();
|
||||
for (String name : pathVars.getAllMacroNames()) {
|
||||
final String path = pathVars.getValue(name);
|
||||
if (path != null) {
|
||||
@@ -716,7 +725,7 @@ public class BuildManager implements ApplicationComponent{
|
||||
}
|
||||
}
|
||||
|
||||
return cmdBuilder.build();
|
||||
return myGlobals = cmdBuilder.build();
|
||||
}
|
||||
|
||||
private OSProcessHandler launchBuildProcess(Project project, final int port, final UUID sessionId) throws ExecutionException {
|
||||
@@ -827,6 +836,7 @@ public class BuildManager implements ApplicationComponent{
|
||||
cmdLine.addParameter("-D"+ GlobalOptions.GENERATE_CLASSPATH_INDEX_OPTION +"=" + shouldGenerateIndex);
|
||||
}
|
||||
cmdLine.addParameter("-D"+ GlobalOptions.COMPILE_PARALLEL_OPTION +"=" + Boolean.toString(config.PARALLEL_COMPILATION));
|
||||
cmdLine.addParameter("-D"+ GlobalOptions.REBUILD_ON_DEPENDENCY_CHANGE_OPTION + "=" + Boolean.toString(config.REBUILD_ON_DEPENDENCY_CHANGE));
|
||||
|
||||
if (Boolean.TRUE.equals(Boolean.valueOf(System.getProperty("java.net.preferIPv4Stack", "false")))) {
|
||||
cmdLine.addParameter("-Djava.net.preferIPv4Stack=true");
|
||||
@@ -876,7 +886,7 @@ public class BuildManager implements ApplicationComponent{
|
||||
workDirectory.mkdirs();
|
||||
ensureLogConfigExists(workDirectory);
|
||||
|
||||
cmdLine.addParameter("-Djava.io.tmpdir=" + FileUtil.toSystemIndependentName(workDirectory.getPath()) + "/_temp_");
|
||||
cmdLine.addParameter("-Djava.io.tmpdir=" + FileUtil.toSystemIndependentName(workDirectory.getPath()) + "/" + TEMP_DIR_NAME);
|
||||
|
||||
final List<String> cp = ClasspathBootstrap.getBuildProcessApplicationClasspath();
|
||||
cp.add(compilerPath);
|
||||
|
||||
@@ -42,6 +42,7 @@ public class CompilerWorkspaceConfiguration implements PersistentStateComponent<
|
||||
public boolean PARALLEL_COMPILATION = false;
|
||||
public int COMPILER_PROCESS_HEAP_SIZE = DEFAULT_COMPILE_PROCESS_HEAP_SIZE;
|
||||
public String COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS = DEFAULT_COMPILE_PROCESS_VM_OPTIONS;
|
||||
public boolean REBUILD_ON_DEPENDENCY_CHANGE = true;
|
||||
|
||||
public static CompilerWorkspaceConfiguration getInstance(Project project) {
|
||||
return ServiceManager.getService(project, CompilerWorkspaceConfiguration.class);
|
||||
|
||||
@@ -249,21 +249,34 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa
|
||||
}
|
||||
}
|
||||
if (REMOVE_AFTER_HIT) {
|
||||
debugProcess.addDebugProcessListener(new DebugProcessAdapter() {
|
||||
@Override
|
||||
public void resumed(SuspendContext suspendContext) {
|
||||
DebuggerUIUtil.invokeOnEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(Breakpoint.this);
|
||||
}
|
||||
});
|
||||
debugProcess.removeDebugProcessListener(this);
|
||||
}
|
||||
});
|
||||
handleTemporaryBreakpointHit(debugProcess);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTemporaryBreakpointHit(final DebugProcessImpl debugProcess) {
|
||||
debugProcess.addDebugProcessListener(new DebugProcessAdapter() {
|
||||
@Override
|
||||
public void resumed(SuspendContext suspendContext) {
|
||||
removeBreakpoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processDetached(DebugProcess process, boolean closedByUser) {
|
||||
removeBreakpoint();
|
||||
}
|
||||
|
||||
private void removeBreakpoint() {
|
||||
DebuggerUIUtil.invokeOnEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().removeBreakpoint(Breakpoint.this);
|
||||
}
|
||||
});
|
||||
debugProcess.removeDebugProcessListener(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public final void updateUI() {
|
||||
updateUI(EmptyRunnable.getInstance());
|
||||
}
|
||||
|
||||
+6
-1
@@ -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.
|
||||
@@ -616,6 +616,11 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
|
||||
return myDescription;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Alignment getAlignment() {
|
||||
return Alignment.RIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnAction getClickAction() {
|
||||
return new AnAction() {
|
||||
|
||||
@@ -122,9 +122,9 @@ public class OrderEntryAppearanceServiceImpl extends OrderEntryAppearanceService
|
||||
|
||||
String name = jdk.getName();
|
||||
CompositeAppearance appearance = new CompositeAppearance();
|
||||
appearance.setIcon(((SdkType) jdk.getSdkType()).getIcon());
|
||||
VirtualFile homeDirectory = jdk.getHomeDirectory();
|
||||
SimpleTextAttributes attributes = getTextAttributes(homeDirectory != null && homeDirectory.isValid(), selected);
|
||||
SdkType sdkType = (SdkType)jdk.getSdkType();
|
||||
appearance.setIcon(sdkType.getIcon());
|
||||
SimpleTextAttributes attributes = getTextAttributes(sdkType.sdkHasValidPath(jdk), selected);
|
||||
CompositeAppearance.DequeEnd ending = appearance.getEnding();
|
||||
ending.addText(name, attributes);
|
||||
|
||||
|
||||
@@ -147,4 +147,8 @@ public class LocalArchivedTemplate extends ArchivedProjectTemplate {
|
||||
public ZipInputStream getStream() throws IOException {
|
||||
return new ZipInputStream(myArchivePath.openStream());
|
||||
}
|
||||
|
||||
public URL getArchivePath() {
|
||||
return myArchivePath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,17 +21,22 @@ import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.platform.ProjectTemplate;
|
||||
import com.intellij.platform.ProjectTemplatesFactory;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.CollectionListModel;
|
||||
import com.intellij.ui.ColoredListCellRenderer;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.ToolbarDecorator;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListDataEvent;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
@@ -49,7 +54,21 @@ class ManageProjectTemplatesDialog extends DialogWrapper {
|
||||
setTitle("Manage Project Templates");
|
||||
final ProjectTemplate[] templates =
|
||||
new ArchivedTemplatesFactory().createTemplates(ProjectTemplatesFactory.CUSTOM_GROUP, new WizardContext(null));
|
||||
final CollectionListModel<ProjectTemplate> model = new CollectionListModel<ProjectTemplate>(Arrays.asList(templates));
|
||||
final CollectionListModel<ProjectTemplate> model = new CollectionListModel<ProjectTemplate>(Arrays.asList(templates)) {
|
||||
@Override
|
||||
public void remove(int index) {
|
||||
ProjectTemplate template = getElementAt(index);
|
||||
super.remove(index);
|
||||
if (template instanceof LocalArchivedTemplate) {
|
||||
URL path = ((LocalArchivedTemplate)template).getArchivePath();
|
||||
try {
|
||||
new File(path.toURI()).delete();
|
||||
}
|
||||
catch (URISyntaxException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
myTemplatesList = new JBList(model);
|
||||
myTemplatesList.setEmptyText("No user-defined project templates");
|
||||
myTemplatesList.setPreferredSize(new Dimension(300, 100));
|
||||
@@ -66,12 +85,6 @@ class ManageProjectTemplatesDialog extends DialogWrapper {
|
||||
myDescriptionPane.setText(template == null ? null : template.getDescription());
|
||||
}
|
||||
});
|
||||
model.addListDataListener(new ListDataAdapter() {
|
||||
@Override
|
||||
public void intervalRemoved(ListDataEvent e) {
|
||||
ArchivedTemplatesFactory.getTemplateFile(templates[e.getIndex0()].getName()).delete();
|
||||
}
|
||||
});
|
||||
|
||||
myPanel = new JPanel(new BorderLayout(0, 5));
|
||||
myPanel.add(ToolbarDecorator.createDecorator(myTemplatesList).disableUpDownActions().createPanel());
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="269"/>
|
||||
<xy x="20" y="20" width="500" height="171"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -24,7 +24,7 @@
|
||||
<text resource-bundle="messages/ProjectBundle" key="project.new.wizard.import.title"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="b4cdc" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="b4cdc" layout-manager="GridLayoutManager" row-count="1" column-count="1" 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"/>
|
||||
@@ -49,11 +49,6 @@
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
<vspacer id="65df7">
|
||||
<constraints>
|
||||
<grid row="1" 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>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.intellij.ui.DoubleClickListener;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.components.JBRadioButton;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
@@ -50,6 +51,7 @@ public class ImportChooserStep extends ProjectImportWizardStep {
|
||||
|
||||
private final ProjectImportProvider[] myProviders;
|
||||
private final StepSequence mySequence;
|
||||
@Nullable
|
||||
private ProjectImportProvider myFromSourcesProvider;
|
||||
private JBList myList;
|
||||
private JPanel myPanel;
|
||||
@@ -73,7 +75,9 @@ public class ImportChooserStep extends ProjectImportWizardStep {
|
||||
model.addElement(provider);
|
||||
}
|
||||
}
|
||||
|
||||
if (myFromSourcesProvider == null) {
|
||||
myCreateFromSources.setVisible(false);
|
||||
}
|
||||
myList.setModel(model);
|
||||
myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
myList.setCellRenderer(new DefaultListCellRenderer() {
|
||||
@@ -121,7 +125,7 @@ public class ImportChooserStep extends ProjectImportWizardStep {
|
||||
if (myList.getSelectedValue() != null) return;
|
||||
|
||||
final String id = PropertiesComponent.getInstance().getValue(PREFERRED);
|
||||
if (id == null || id.equals(myFromSourcesProvider.getId())) {
|
||||
if (id == null || myFromSourcesProvider != null && id.equals(myFromSourcesProvider.getId())) {
|
||||
myCreateFromSources.setSelected(true);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:johnnyclark@gmail.com">Johnny Clark</a>
|
||||
* Creation Date: 8/3/12
|
||||
*/
|
||||
@State(
|
||||
name = "ConditionCheckManager",
|
||||
storages = {@Storage(id = "dir", file = StoragePathMacros.PROJECT_CONFIG_DIR + "/checker.xml", scheme = StorageScheme.DIRECTORY_BASED)}
|
||||
)
|
||||
public class ConditionCheckManager implements PersistentStateComponent<ConditionCheckManager.State> {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) private State state;
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ConditionCheckManager");
|
||||
|
||||
private List<ConditionChecker> myIsNullCheckMethods = new ArrayList<ConditionChecker>();
|
||||
private List<ConditionChecker> myIsNotNullCheckMethods = new ArrayList<ConditionChecker>();
|
||||
|
||||
private List<ConditionChecker> myAssertIsNullMethods = new ArrayList<ConditionChecker>();
|
||||
private List<ConditionChecker> myAssertIsNotNullMethods = new ArrayList<ConditionChecker>();
|
||||
|
||||
private List<ConditionChecker> myAssertTrueMethods = new ArrayList<ConditionChecker>();
|
||||
private List<ConditionChecker> myAssertFalseMethods = new ArrayList<ConditionChecker>();
|
||||
|
||||
public static ConditionCheckManager getInstance(Project project) {
|
||||
return ServiceManager.getService(project, ConditionCheckManager.class);
|
||||
}
|
||||
|
||||
public void setIsNullCheckMethods(List<ConditionChecker> methodConditionChecks) {
|
||||
myIsNullCheckMethods.clear();
|
||||
myIsNullCheckMethods.addAll(methodConditionChecks);
|
||||
}
|
||||
|
||||
public void setIsNotNullCheckMethods(List<ConditionChecker> methodConditionChecks) {
|
||||
myIsNotNullCheckMethods.clear();
|
||||
myIsNotNullCheckMethods.addAll(methodConditionChecks);
|
||||
}
|
||||
|
||||
public void setAssertIsNullMethods(List<ConditionChecker> methodConditionChecks) {
|
||||
myAssertIsNullMethods.clear();
|
||||
myAssertIsNullMethods.addAll(methodConditionChecks);
|
||||
}
|
||||
|
||||
public void setAssertIsNotNullMethods(List<ConditionChecker> methodConditionChecks) {
|
||||
myAssertIsNotNullMethods.clear();
|
||||
myAssertIsNotNullMethods.addAll(methodConditionChecks);
|
||||
}
|
||||
|
||||
public void setAssertTrueMethods(List<ConditionChecker> psiMethodWrappers) {
|
||||
myAssertTrueMethods.clear();
|
||||
myAssertTrueMethods.addAll(psiMethodWrappers);
|
||||
}
|
||||
|
||||
public void setAssertFalseMethods(List<ConditionChecker> psiMethodWrappers) {
|
||||
myAssertFalseMethods.clear();
|
||||
myAssertFalseMethods.addAll(psiMethodWrappers);
|
||||
}
|
||||
|
||||
public List<ConditionChecker> getIsNullCheckMethods() {
|
||||
return myIsNullCheckMethods;
|
||||
}
|
||||
|
||||
public List<ConditionChecker> getIsNotNullCheckMethods() {
|
||||
return myIsNotNullCheckMethods;
|
||||
}
|
||||
|
||||
public List<ConditionChecker> getAssertIsNullMethods() {
|
||||
return myAssertIsNullMethods;
|
||||
}
|
||||
|
||||
public List<ConditionChecker> getAssertIsNotNullMethods() {
|
||||
return myAssertIsNotNullMethods;
|
||||
}
|
||||
|
||||
public List<ConditionChecker> getAssertFalseMethods() {
|
||||
return myAssertFalseMethods;
|
||||
}
|
||||
|
||||
public List<ConditionChecker> getAssertTrueMethods() {
|
||||
return myAssertTrueMethods;
|
||||
}
|
||||
|
||||
public static class State {
|
||||
public List<String> myIsNullCheckMethods = new ArrayList<String>();
|
||||
public List<String> myIsNotNullCheckMethods = new ArrayList<String>();
|
||||
public List<String> myAssertIsNullMethods = new ArrayList<String>();
|
||||
public List<String> myAssertIsNotNullMethods = new ArrayList<String>();
|
||||
public List<String> myAssertTrueMethods = new ArrayList<String>();
|
||||
public List<String> myAssertFalseMethods = new ArrayList<String>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public State getState() {
|
||||
State state = new State();
|
||||
|
||||
loadMethodChecksToState(state.myIsNullCheckMethods, myIsNullCheckMethods);
|
||||
loadMethodChecksToState(state.myIsNotNullCheckMethods, myIsNotNullCheckMethods);
|
||||
loadMethodChecksToState(state.myAssertIsNullMethods, myAssertIsNullMethods);
|
||||
loadMethodChecksToState(state.myAssertIsNotNullMethods, myAssertIsNotNullMethods);
|
||||
loadMethodChecksToState(state.myAssertTrueMethods, myAssertTrueMethods);
|
||||
loadMethodChecksToState(state.myAssertFalseMethods, myAssertFalseMethods);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
private static void loadMethodChecksToState(List<String> listToLoadTo, List<ConditionChecker> listToLoadFrom) {
|
||||
for (ConditionChecker checker : listToLoadFrom) {
|
||||
listToLoadTo.add(checker.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadState(State state) {
|
||||
this.state = state;
|
||||
loadMethods(myIsNullCheckMethods, state.myIsNullCheckMethods, ConditionChecker.Type.IS_NULL_METHOD);
|
||||
loadMethods(myIsNotNullCheckMethods, state.myIsNotNullCheckMethods, ConditionChecker.Type.IS_NOT_NULL_METHOD);
|
||||
loadMethods(myAssertIsNullMethods, state.myAssertIsNullMethods, ConditionChecker.Type.ASSERT_IS_NULL_METHOD);
|
||||
loadMethods(myAssertIsNotNullMethods, state.myAssertIsNotNullMethods, ConditionChecker.Type.ASSERT_IS_NOT_NULL_METHOD);
|
||||
loadMethods(myAssertTrueMethods, state.myAssertTrueMethods, ConditionChecker.Type.ASSERT_TRUE_METHOD);
|
||||
loadMethods(myAssertFalseMethods, state.myAssertFalseMethods, ConditionChecker.Type.ASSERT_FALSE_METHOD);
|
||||
}
|
||||
|
||||
public void loadMethods(List<ConditionChecker> listToLoadTo, List<String> listToLoadFrom, ConditionChecker.Type type){
|
||||
listToLoadTo.clear();
|
||||
for (String setting : listToLoadFrom) {
|
||||
try {
|
||||
listToLoadTo.add(new ConditionChecker.FromConfigBuilder(setting, type).build());
|
||||
} catch (Exception e) {
|
||||
LOG.error("Problem occurred while attempting to load Condition Check from configuration file. " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isMethod(@NotNull PsiMethod psiMethod, List<ConditionChecker> checkers) {
|
||||
for (ConditionChecker checker : checkers) {
|
||||
if (checker.matchesPsiMethod(psiMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isCheck(PsiMethod psiMethod) {
|
||||
ConditionCheckManager manager = getInstance(psiMethod.getProject());
|
||||
return isMethod(psiMethod, manager.getIsNullCheckMethods()) ||
|
||||
isMethod(psiMethod, manager.getIsNotNullCheckMethods()) ||
|
||||
isMethod(psiMethod, manager.getAssertIsNullMethods()) ||
|
||||
isMethod(psiMethod, manager.getAssertIsNotNullMethods()) ||
|
||||
isAssertTrueCheckMethod(psiMethod) ||
|
||||
isAssertFalseCheckMethod(psiMethod);
|
||||
}
|
||||
|
||||
public static boolean isNullCheckMethod(PsiMethod psiMethod) {
|
||||
return methodMatches(psiMethod, getInstance(psiMethod.getProject()).getIsNullCheckMethods());
|
||||
}
|
||||
|
||||
public static boolean isNotNullCheckMethod(PsiMethod psiMethod) {
|
||||
return methodMatches(psiMethod, getInstance(psiMethod.getProject()).getIsNotNullCheckMethods());
|
||||
}
|
||||
|
||||
public static boolean isAssertIsNullCheckMethod(PsiMethod psiMethod) {
|
||||
return methodMatches(psiMethod, getInstance(psiMethod.getProject()).getAssertIsNullMethods());
|
||||
}
|
||||
|
||||
public static boolean isAssertIsNotNullCheckMethod(PsiMethod psiMethod) {
|
||||
return methodMatches(psiMethod, getInstance(psiMethod.getProject()).getAssertIsNotNullMethods());
|
||||
}
|
||||
|
||||
public static boolean isAssertTrueCheckMethod(PsiMethod psiMethod) {
|
||||
return methodMatches(psiMethod, getInstance(psiMethod.getProject()).getAssertTrueMethods());
|
||||
}
|
||||
|
||||
public static boolean isAssertFalseCheckMethod(PsiMethod psiMethod) {
|
||||
return methodMatches(psiMethod, getInstance(psiMethod.getProject()).getAssertFalseMethods());
|
||||
}
|
||||
|
||||
public static boolean isNullCheckMethod(PsiMethod psiMethod, int paramIndex) {
|
||||
return methodMatches(psiMethod, paramIndex, getInstance(psiMethod.getProject()).getIsNullCheckMethods());
|
||||
}
|
||||
|
||||
public static boolean isNotNullCheckMethod(PsiMethod psiMethod, int paramIndex) {
|
||||
return methodMatches(psiMethod, paramIndex, getInstance(psiMethod.getProject()).getIsNotNullCheckMethods());
|
||||
}
|
||||
|
||||
public static boolean isAssertIsNullCheckMethod(PsiMethod psiMethod, int paramIndex) {
|
||||
return methodMatches(psiMethod, paramIndex, getInstance(psiMethod.getProject()).getAssertIsNullMethods());
|
||||
}
|
||||
|
||||
public static boolean isAssertIsNotNullCheckMethod(PsiMethod psiMethod, int paramIndex) {
|
||||
return methodMatches(psiMethod, paramIndex, getInstance(psiMethod.getProject()).getAssertIsNotNullMethods());
|
||||
}
|
||||
|
||||
public static boolean isAssertTrueCheckMethod(PsiMethod psiMethod, int paramIndex) {
|
||||
return methodMatches(psiMethod, paramIndex, getInstance(psiMethod.getProject()).getAssertTrueMethods());
|
||||
}
|
||||
|
||||
public static boolean isAssertFalseCheckMethod(PsiMethod psiMethod, int paramIndex) {
|
||||
return methodMatches(psiMethod, paramIndex, getInstance(psiMethod.getProject()).getAssertFalseMethods());
|
||||
}
|
||||
|
||||
public static boolean methodMatches(PsiMethod psiMethod, List<ConditionChecker> checkers) {
|
||||
for (ConditionChecker checker : checkers) {
|
||||
if (checker.matchesPsiMethod(psiMethod))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean methodMatches(PsiMethod psiMethod, int paramIndex, List<ConditionChecker> checkers) {
|
||||
for (ConditionChecker checker : checkers) {
|
||||
if (checker.matchesPsiMethod(psiMethod, paramIndex))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,431 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.intellij.openapi.diagnostic.*;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* Used by Constant Condition Inspection to identify methods which perform some type of Validation on the parameters passed into them.
|
||||
* For example given the following method
|
||||
* <pre>
|
||||
* {@code
|
||||
* class Foo {
|
||||
* static boolean validateNotNull(Object o) {
|
||||
* if (o == null) return false;
|
||||
* else return true;
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* The corresponding ConditionCheck would be <p/>
|
||||
* myConditionCheckType=Type.IS_NOT_NULL_METHOD
|
||||
* myClassName=Foo
|
||||
* myMethodName=validateNotNull
|
||||
* myPsiParameter=o
|
||||
*
|
||||
* The following block of code would produce a Inspection Warning that o is always true
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* if (Value.isNotNull(o)) {
|
||||
* if(o != null) {}
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author <a href="mailto:johnnyclark@gmail.com">Johnny Clark</a>
|
||||
* Creation Date: 8/14/12
|
||||
*/
|
||||
public class ConditionChecker implements Serializable {
|
||||
private final @NotNull Type myConditionCheckType;
|
||||
|
||||
public enum Type {
|
||||
IS_NULL_METHOD("IsNull Method"),
|
||||
IS_NOT_NULL_METHOD("IsNotNull Method"),
|
||||
ASSERT_IS_NULL_METHOD("Assert IsNull Method"),
|
||||
ASSERT_IS_NOT_NULL_METHOD("Assert IsNotNull Method"),
|
||||
ASSERT_TRUE_METHOD("Assert True Method"),
|
||||
ASSERT_FALSE_METHOD("Assert False Method");
|
||||
private final String myStringRepresentation;
|
||||
|
||||
Type(String stringRepresentation) {
|
||||
myStringRepresentation = stringRepresentation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myStringRepresentation;
|
||||
}
|
||||
}
|
||||
|
||||
private final @NotNull String myClassName;
|
||||
private final @NotNull String myMethodName;
|
||||
private final @NotNull List<String> myParameterClassList;
|
||||
private final int myCheckedParameterIndex;
|
||||
private final String myFullName;
|
||||
|
||||
private ConditionChecker(@NotNull String className,
|
||||
@NotNull String methodName,
|
||||
@NotNull List<String> parameterClassList,
|
||||
int checkedParameterIndex,
|
||||
@NotNull Type type,
|
||||
@NotNull String fullName) {
|
||||
checkState(!className.isEmpty(), "Class Name is blank");
|
||||
checkState(!methodName.isEmpty(), "Method Name is blank");
|
||||
checkState(!parameterClassList.isEmpty(), "Parameter Class List is empty");
|
||||
checkState(checkedParameterIndex >= 0, "CheckedParameterIndex must be greater than or equal to zero");
|
||||
checkState(parameterClassList.size() >= checkedParameterIndex, "CheckedParameterIndex is greater than Parameter Class List's size");
|
||||
checkState(!fullName.isEmpty(), "Method Name is blank");
|
||||
|
||||
myConditionCheckType = type;
|
||||
myClassName = className;
|
||||
myMethodName = methodName;
|
||||
myParameterClassList = parameterClassList;
|
||||
myCheckedParameterIndex = checkedParameterIndex;
|
||||
myFullName = fullName;
|
||||
}
|
||||
|
||||
private static void checkState(boolean condition, String errorMsg) {
|
||||
if (!condition) throw new IllegalArgumentException(errorMsg);
|
||||
}
|
||||
|
||||
public static String getFullyQualifiedName(PsiParameter psiParameter) {
|
||||
PsiTypeElement typeElement = psiParameter.getTypeElement();
|
||||
if (typeElement == null) throw new RuntimeException("Parameter has null typeElement " + psiParameter.getName());
|
||||
|
||||
PsiType psiType = typeElement.getType();
|
||||
|
||||
return psiType.getCanonicalText();
|
||||
}
|
||||
|
||||
public boolean matchesPsiMethod(PsiMethod psiMethod) {
|
||||
if (!myMethodName.equals(psiMethod.getName())) return false;
|
||||
|
||||
PsiClass containingClass = psiMethod.getContainingClass();
|
||||
if (containingClass == null) return false;
|
||||
|
||||
String qualifiedName = containingClass.getQualifiedName();
|
||||
if (qualifiedName == null) return false;
|
||||
|
||||
if (!myClassName.equals(qualifiedName)) return false;
|
||||
|
||||
PsiParameterList psiParameterList = psiMethod.getParameterList();
|
||||
if (myParameterClassList.size() != psiParameterList.getParameters().length) return false;
|
||||
|
||||
for (int i = 0; i < psiParameterList.getParameters().length; i++) {
|
||||
PsiParameter psiParameter = psiParameterList.getParameters()[i];
|
||||
PsiTypeElement psiTypeElement = psiParameter.getTypeElement();
|
||||
if (psiTypeElement == null) return false;
|
||||
|
||||
PsiType psiType = psiTypeElement.getType();
|
||||
String parameterCanonicalText = psiType.getCanonicalText();
|
||||
String myParameterCanonicalText = myParameterClassList.get(i);
|
||||
if (!myParameterCanonicalText.equals(parameterCanonicalText)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean matchesPsiMethod(PsiMethod psiMethod, int paramIndex) {
|
||||
if (matchesPsiMethod(psiMethod) && paramIndex == myCheckedParameterIndex) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean overlaps(ConditionChecker otherChecker) {
|
||||
if (myClassName.equals(otherChecker.myClassName) &&
|
||||
myMethodName.equals(otherChecker.myMethodName) &&
|
||||
myParameterClassList.equals(otherChecker.myParameterClassList) &&
|
||||
myCheckedParameterIndex == otherChecker.myCheckedParameterIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Type getConditionCheckType() {
|
||||
return myConditionCheckType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getClassName() {
|
||||
return myClassName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getMethodName() {
|
||||
return myMethodName;
|
||||
}
|
||||
|
||||
public int getCheckedParameterIndex() {
|
||||
return myCheckedParameterIndex;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return myFullName;
|
||||
}
|
||||
|
||||
/**
|
||||
* In addition to normal duties, this controls the manner in which the ConditionCheck appears in the ConditionCheckDialog.MethodsPanel
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return myFullName;
|
||||
}
|
||||
|
||||
private static class Builder {
|
||||
|
||||
static String initFullName(String className,
|
||||
String methodName,
|
||||
List<String> parameterClasses,
|
||||
List<String> parameterNames,
|
||||
int checkedParameterIndex) {
|
||||
String s = className + "." + methodName + "(";
|
||||
int index = 0;
|
||||
for (String parameterClass : parameterClasses) {
|
||||
String parameterClassAndName = parameterClass + " " + parameterNames.get(index);
|
||||
if (index == checkedParameterIndex) parameterClassAndName = "*" + parameterClassAndName + "*";
|
||||
|
||||
s += parameterClassAndName + ", ";
|
||||
index++;
|
||||
}
|
||||
s = s.substring(0, s.length() - 2);
|
||||
s += ")";
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
static class FromConfigBuilder extends Builder {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ConditionCheck.FromConfigBuilder");
|
||||
private final @NotNull String serializedRepresentation;
|
||||
private final @NotNull Type type;
|
||||
|
||||
FromConfigBuilder(@NotNull String serializedRepresentation, @NotNull Type type) {
|
||||
this.serializedRepresentation = serializedRepresentation;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
private String parseClassAndMethodName() {
|
||||
if (!serializedRepresentation.contains("(")) {
|
||||
throw new IllegalArgumentException("Name should contain a opening parenthesis. " + serializedRepresentation);
|
||||
}
|
||||
else if (!serializedRepresentation.contains(")")) {
|
||||
throw new IllegalArgumentException("Name should contain a closing parenthesis. " + serializedRepresentation);
|
||||
}
|
||||
else if (serializedRepresentation.indexOf("(", serializedRepresentation.indexOf("(") + 1) > -1) {
|
||||
throw new IllegalArgumentException("Name should only contain one opening parenthesis. " + serializedRepresentation);
|
||||
}
|
||||
else if (serializedRepresentation.indexOf(")", serializedRepresentation.indexOf(")") + 1) > -1) {
|
||||
throw new IllegalArgumentException("Name should only contain one closing parenthesis. " + serializedRepresentation);
|
||||
}
|
||||
else if (serializedRepresentation.indexOf(")") < serializedRepresentation.indexOf("(")) {
|
||||
throw new IllegalArgumentException("Opening parenthesis should precede closing parenthesis. " + serializedRepresentation);
|
||||
}
|
||||
|
||||
String classAndMethodName = serializedRepresentation.substring(0, serializedRepresentation.indexOf("("));
|
||||
if (!classAndMethodName.contains(".")) {
|
||||
throw new IllegalArgumentException(
|
||||
"Name should contain a dot between the class name and method name (before the opening parenthesis). " +
|
||||
serializedRepresentation);
|
||||
}
|
||||
return classAndMethodName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ConditionChecker build() {
|
||||
try {
|
||||
String classAndMethodName = parseClassAndMethodName();
|
||||
|
||||
String className = classAndMethodName.substring(0, classAndMethodName.lastIndexOf("."));
|
||||
String methodName = classAndMethodName.substring(classAndMethodName.lastIndexOf(".") + 1);
|
||||
|
||||
String allParametersSubString =
|
||||
serializedRepresentation.substring(serializedRepresentation.indexOf("(") + 1, serializedRepresentation.lastIndexOf(")")).trim();
|
||||
if (allParametersSubString.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Name should contain 1+ parameter (between opening and closing parenthesis). " + serializedRepresentation);
|
||||
}
|
||||
else if (allParametersSubString.contains("*") && allParametersSubString.indexOf("*") == allParametersSubString.lastIndexOf("*")) {
|
||||
throw new IllegalArgumentException("Selected Parameter should be surrounded by asterisks. " + serializedRepresentation);
|
||||
}
|
||||
|
||||
List<String> parameterClasses = new ArrayList<String>();
|
||||
List<String> parameterNames = new ArrayList<String>();
|
||||
int checkParameterIndex = -1;
|
||||
int index = 0;
|
||||
for (String parameterClassAndName : allParametersSubString.split(",")) {
|
||||
parameterClassAndName = parameterClassAndName.trim();
|
||||
if (parameterClassAndName.startsWith("*") && parameterClassAndName.endsWith("*")) {
|
||||
checkParameterIndex = index;
|
||||
parameterClassAndName = parameterClassAndName.substring(1, parameterClassAndName.length() - 1);
|
||||
}
|
||||
|
||||
String[] parameterClassAndNameSplit = parameterClassAndName.split(" ");
|
||||
String parameterClass = parameterClassAndNameSplit[0];
|
||||
String parameterName = parameterClassAndNameSplit[1];
|
||||
parameterClasses.add(parameterClass);
|
||||
parameterNames.add(parameterName);
|
||||
index++;
|
||||
}
|
||||
String fullName = initFullName(className, methodName, parameterClasses, parameterNames, checkParameterIndex);
|
||||
return new ConditionChecker(className, methodName, parameterClasses, checkParameterIndex, type, fullName);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error("An Exception occurred while attempting to build ConditionCheck for Serialized String '" +
|
||||
serializedRepresentation +
|
||||
"' and Type '" +
|
||||
type +
|
||||
"'", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class FromPsiBuilder extends Builder {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ConditionCheck.FromPsiBuilder");
|
||||
private final @NotNull PsiMethod psiMethod;
|
||||
private final @NotNull PsiParameter psiParameter;
|
||||
private final @NotNull Type type;
|
||||
|
||||
public FromPsiBuilder(@NotNull PsiMethod psiMethod, @NotNull PsiParameter psiParameter, @NotNull Type type) {
|
||||
this.psiMethod = psiMethod;
|
||||
this.psiParameter = psiParameter;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
private static void validatePsiMethodHasContainingClass(PsiMethod psiMethod) {
|
||||
PsiElement psiElement = psiMethod.getContainingClass();
|
||||
if (!(psiElement instanceof PsiClass)) {
|
||||
throw new IllegalArgumentException("PsiMethod " + psiMethod + " can not have a null containing class.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void validatePsiMethodReturnTypeForNonAsserts(PsiMethod psiMethod, Type type) {
|
||||
PsiType returnType = psiMethod.getReturnType();
|
||||
if (isAssert(type)) return;
|
||||
|
||||
if (returnType == null) throw new IllegalArgumentException("PsiMethod " + psiMethod + " has a null return type PsiType.");
|
||||
|
||||
if (returnType != PsiType.BOOLEAN && !returnType.getCanonicalText().equals(Boolean.class.toString())) {
|
||||
throw new IllegalArgumentException("PsiMethod " + psiMethod + " must have a null return type PsiType of boolean or Boolean.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void validatePsiParameterExistsInPsiMethod(PsiMethod psiMethod, PsiParameter psiParameter) {
|
||||
boolean parameterFound = false;
|
||||
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
|
||||
for (PsiParameter parameter : parameters) {
|
||||
if (psiParameter.equals(parameter)) {
|
||||
parameterFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!parameterFound) {
|
||||
throw new IllegalArgumentException("PsiMethod " + psiMethod + " must have parameter " + getFullyQualifiedName(psiParameter));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isAssert(Type type) {
|
||||
return type == Type.ASSERT_IS_NULL_METHOD ||
|
||||
type == Type.ASSERT_IS_NOT_NULL_METHOD ||
|
||||
type == Type.ASSERT_TRUE_METHOD ||
|
||||
type == Type.ASSERT_FALSE_METHOD;
|
||||
}
|
||||
|
||||
private static String initClassNameFromPsiMethod(PsiMethod psiMethod) {
|
||||
PsiElement psiElement = psiMethod.getContainingClass();
|
||||
PsiClass psiClass = (PsiClass)psiElement;
|
||||
if (psiClass == null) throw new IllegalStateException("PsiClass is null");
|
||||
|
||||
String qualifiedName = psiClass.getQualifiedName();
|
||||
if (qualifiedName == null || qualifiedName.isEmpty()) throw new IllegalStateException("Qualified Name is Blank");
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
private static String initMethodNameFromPsiMethod(PsiMethod psiMethod) {
|
||||
return psiMethod.getName();
|
||||
}
|
||||
|
||||
private static List<String> initParameterClassListFromPsiMethod(PsiMethod psiMethod) {
|
||||
List<String> parameterClasses = new ArrayList<String>();
|
||||
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
|
||||
for (PsiParameter param : parameters) {
|
||||
PsiTypeElement typeElement = param.getTypeElement();
|
||||
if (typeElement == null) throw new RuntimeException("Parameter has null typeElement " + param.getName());
|
||||
|
||||
PsiType psiType = typeElement.getType();
|
||||
|
||||
parameterClasses.add(psiType.getCanonicalText());
|
||||
}
|
||||
return parameterClasses;
|
||||
}
|
||||
|
||||
private static List<String> initParameterNameListFromPsiMethod(PsiMethod psiMethod) {
|
||||
List<String> parameterNames = new ArrayList<String>();
|
||||
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
|
||||
for (PsiParameter param : parameters) {
|
||||
parameterNames.add(param.getName());
|
||||
}
|
||||
return parameterNames;
|
||||
}
|
||||
|
||||
private static int initCheckedParameterIndex(PsiMethod psiMethod, PsiParameter psiParameterToFind) {
|
||||
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
PsiParameter param = parameters[i];
|
||||
if (param.equals(psiParameterToFind)) return i;
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
private void validateConstructorArgs(PsiMethod psiMethod, PsiParameter psiParameter) {
|
||||
validatePsiMethodHasContainingClass(psiMethod);
|
||||
validatePsiMethodReturnTypeForNonAsserts(psiMethod, type);
|
||||
validatePsiParameterExistsInPsiMethod(psiMethod, psiParameter);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ConditionChecker build() {
|
||||
try {
|
||||
validateConstructorArgs(psiMethod, psiParameter);
|
||||
|
||||
String className = initClassNameFromPsiMethod(psiMethod);
|
||||
String methodName = initMethodNameFromPsiMethod(psiMethod);
|
||||
List<String> parameterClassList = initParameterClassListFromPsiMethod(psiMethod);
|
||||
List<String> parameterNameList = initParameterNameListFromPsiMethod(psiMethod);
|
||||
int checkedParameterIndex = initCheckedParameterIndex(psiMethod, psiParameter);
|
||||
String fullName = initFullName(className, methodName, parameterClassList, parameterNameList, checkedParameterIndex);
|
||||
return new ConditionChecker(className, methodName, parameterClassList, checkedParameterIndex, type, fullName);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error("An Exception occurred while attempting to build ConditionCheck for PsiMethod '" + psiMethod +
|
||||
"' PsiParameter='" + psiParameter + "' " +
|
||||
"' and Type '" +
|
||||
type +
|
||||
"'", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,24 +118,10 @@ public class TailTypes {
|
||||
return styleSettings.SPACE_WITHIN_IF_PARENTHESES;
|
||||
}
|
||||
};
|
||||
public static final TailType FINALLY_LBRACE = new BracesTailType() {
|
||||
@Override
|
||||
protected boolean isSpaceBeforeLBrace(final CommonCodeStyleSettings styleSettings, final Editor editor, final int tailOffset) {
|
||||
return styleSettings.SPACE_BEFORE_FINALLY_LBRACE;
|
||||
}
|
||||
};
|
||||
public static final TailType TRY_LBRACE = new BracesTailType() {
|
||||
@Override
|
||||
protected boolean isSpaceBeforeLBrace(CommonCodeStyleSettings styleSettings, Editor editor, int tailOffset) {
|
||||
return styleSettings.SPACE_BEFORE_TRY_LBRACE;
|
||||
}
|
||||
};
|
||||
public static final TailType DO_LBRACE = new BracesTailType() {
|
||||
@Override
|
||||
protected boolean isSpaceBeforeLBrace(CommonCodeStyleSettings styleSettings, Editor editor, int tailOffset) {
|
||||
return styleSettings.SPACE_BEFORE_DO_LBRACE;
|
||||
}
|
||||
};
|
||||
private static final TailType BRACES = new BracesTailType();
|
||||
public static final TailType FINALLY_LBRACE = BRACES;
|
||||
public static final TailType TRY_LBRACE = BRACES;
|
||||
public static final TailType DO_LBRACE = BRACES;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementDecorator;
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation;
|
||||
import com.intellij.codeInsight.lookup.TypedLookupItem;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.diagnostic.LogMessageEx;
|
||||
import com.intellij.diagnostic.errordialog.Attachment;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -97,8 +94,9 @@ public class JavaChainLookupElement extends LookupElementDecorator<LookupElement
|
||||
final String qualifierText = myQualifier.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null ? "(" + name + ")" : name;
|
||||
presentation.setItemText(qualifierText + "." + presentation.getItemText());
|
||||
|
||||
if (getQualifierObject() instanceof PsiClass) {
|
||||
presentation.setTailText(StringUtil.notNullize(presentation.getTailText()) + qualifierPresentation.getTailText());
|
||||
if (myQualifier instanceof LookupItem && getQualifierObject() instanceof PsiClass) {
|
||||
String locationString = JavaPsiClassReferenceElement.getLocationString((LookupItem)myQualifier);
|
||||
presentation.setTailText(StringUtil.notNullize(presentation.getTailText()) + locationString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-33
@@ -24,7 +24,6 @@ import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PsiJavaPatterns;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
@@ -366,46 +365,36 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
|
||||
final boolean staticContext,
|
||||
final PsiType varType,
|
||||
final PsiElement element) {
|
||||
class Change implements Runnable {
|
||||
private String[] result;
|
||||
final List<String> propertyHandlers = new ArrayList<String>();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final List<String> propertyHandlers = new ArrayList<String>();
|
||||
final PsiField[] fields = psiClass.getFields();
|
||||
for (final PsiField field : psiClass.getFields()) {
|
||||
if (field == element) continue;
|
||||
|
||||
for (final PsiField field : fields) {
|
||||
if (field == element) continue;
|
||||
assert field.isValid() : "invalid field: " + field;
|
||||
PsiType fieldType = field.getType();
|
||||
assert fieldType.isValid() : "invalid field type: " + field + "; " + fieldType + " of " + fieldType.getClass();
|
||||
|
||||
assert field.isValid() : "invalid field: " + field;
|
||||
PsiType fieldType = field.getType();
|
||||
assert fieldType.isValid() : "invalid field type: " + field + "; " + fieldType + " of " + fieldType.getClass();
|
||||
final PsiModifierList modifierList = field.getModifierList();
|
||||
if (staticContext && (modifierList != null && !modifierList.hasModifierProperty(PsiModifier.STATIC))) continue;
|
||||
|
||||
final PsiModifierList modifierList = field.getModifierList();
|
||||
if (staticContext && (modifierList != null && !modifierList.hasModifierProperty(PsiModifier.STATIC))) continue;
|
||||
if (fieldType.equals(varType)) {
|
||||
final String getterName = PropertyUtil.suggestGetterName(field.getProject(), field);
|
||||
if ((psiClass.findMethodsByName(getterName, true).length == 0 ||
|
||||
psiClass.findMethodBySignature(PropertyUtil.generateGetterPrototype(field), true) == null)) {
|
||||
propertyHandlers.add(getterName);
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldType.equals(varType)) {
|
||||
final String getterName = PropertyUtil.suggestGetterName(field.getProject(), field);
|
||||
if ((psiClass.findMethodsByName(getterName, true).length == 0 ||
|
||||
psiClass.findMethodBySignature(PropertyUtil.generateGetterPrototype(field), true) == null)) {
|
||||
propertyHandlers.add(getterName);
|
||||
}
|
||||
}
|
||||
|
||||
if (PsiType.VOID.equals(varType)) {
|
||||
final String setterName = PropertyUtil.suggestSetterName(field.getProject(), field);
|
||||
if ((psiClass.findMethodsByName(setterName, true).length == 0 ||
|
||||
psiClass.findMethodBySignature(PropertyUtil.generateSetterPrototype(field), true) == null)) {
|
||||
propertyHandlers.add(setterName);
|
||||
}
|
||||
}
|
||||
if (PsiType.VOID.equals(varType)) {
|
||||
final String setterName = PropertyUtil.suggestSetterName(field.getProject(), field);
|
||||
if ((psiClass.findMethodsByName(setterName, true).length == 0 ||
|
||||
psiClass.findMethodBySignature(PropertyUtil.generateSetterPrototype(field), true) == null)) {
|
||||
propertyHandlers.add(setterName);
|
||||
}
|
||||
result = ArrayUtil.toStringArray(propertyHandlers);
|
||||
}
|
||||
}
|
||||
final Change result = new Change();
|
||||
CodeStyleManager.getInstance(element.getProject()).performActionWithFormatterDisabled(result);
|
||||
return result.result;
|
||||
|
||||
return ArrayUtil.toStringArray(propertyHandlers);
|
||||
}
|
||||
|
||||
private static void addLookupItems(Set<LookupElement> lookupElements, @Nullable final SuggestedNameInfo callback, PrefixMatcher matcher, Project project, String... strings) {
|
||||
|
||||
+5
-1
@@ -152,7 +152,7 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> {
|
||||
presentation.setStrikeout(strikeout);
|
||||
presentation.setItemTextBold(bold);
|
||||
|
||||
String tailText = StringUtil.notNullize((String) item.getAttribute(LookupItem.TAIL_TEXT_ATTR));
|
||||
String tailText = getLocationString(item);
|
||||
PsiSubstitutor substitutor = (PsiSubstitutor)item.getAttribute(LookupItem.SUBSTITUTOR);
|
||||
|
||||
if (item instanceof PsiTypeLookupItem) {
|
||||
@@ -173,6 +173,10 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> {
|
||||
presentation.setTailText(tailText, true);
|
||||
}
|
||||
|
||||
public static String getLocationString(LookupItem item) {
|
||||
return StringUtil.notNullize((String)item.getAttribute(LookupItem.TAIL_TEXT_ATTR));
|
||||
}
|
||||
|
||||
private static String getName(final PsiClass psiClass, final LookupItem<?> item, boolean diamond) {
|
||||
if (item instanceof JavaPsiClassReferenceElement) {
|
||||
String forced = ((JavaPsiClassReferenceElement)item).getForcedPresentableName();
|
||||
|
||||
@@ -23,22 +23,31 @@ import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class BracesTailType extends TailType {
|
||||
|
||||
protected abstract boolean isSpaceBeforeLBrace(CommonCodeStyleSettings styleSettings, Editor editor, final int tailOffset);
|
||||
public class BracesTailType extends TailType {
|
||||
|
||||
@Override
|
||||
public int processTail(final Editor editor, int tailOffset) {
|
||||
final CommonCodeStyleSettings styleSettings = getLocalCodeStyleSettings(editor, tailOffset);
|
||||
if (isSpaceBeforeLBrace(styleSettings, editor, tailOffset)) {
|
||||
tailOffset = insertChar(editor, tailOffset, ' ');
|
||||
int startOffset = tailOffset;
|
||||
|
||||
CharSequence seq = editor.getDocument().getCharsSequence();
|
||||
int nextNonWs = CharArrayUtil.shiftForward(seq, tailOffset, " \t");
|
||||
if (nextNonWs < seq.length() && seq.charAt(nextNonWs) == '{') {
|
||||
tailOffset = nextNonWs + 1;
|
||||
} else {
|
||||
tailOffset = insertChar(editor, startOffset, '{');
|
||||
}
|
||||
tailOffset = insertChar(editor, tailOffset, '{');
|
||||
|
||||
tailOffset = reformatBrace(editor, tailOffset, startOffset);
|
||||
|
||||
if (EnterAfterUnmatchedBraceHandler.isAfterUnmatchedLBrace(editor, tailOffset, getFileType(editor))) {
|
||||
new EnterHandler(EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_ENTER))
|
||||
.executeWriteAction(editor, DataManager.getInstance().getDataContext(editor.getContentComponent()));
|
||||
@@ -47,4 +56,16 @@ public abstract class BracesTailType extends TailType {
|
||||
return tailOffset;
|
||||
}
|
||||
|
||||
private static int reformatBrace(Editor editor, int tailOffset, int startOffset) {
|
||||
Project project = editor.getProject();
|
||||
if (project != null) {
|
||||
PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
|
||||
if (psiFile != null) {
|
||||
editor.getCaretModel().moveToOffset(tailOffset);
|
||||
CodeStyleManager.getInstance(project).reformatText(psiFile, startOffset, tailOffset);
|
||||
tailOffset = editor.getCaretModel().getOffset();
|
||||
}
|
||||
}
|
||||
return tailOffset;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.editor.ElementColorProvider;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.ui.ColorUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -147,7 +148,7 @@ public class JavaColorProvider implements ElementColorProvider {
|
||||
private static void replaceInt(PsiExpression expr, int newValue, boolean hex) {
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(expr.getProject());
|
||||
if (getInt(expr) != newValue) {
|
||||
String text = hex ? "0x" + Integer.toHexString(newValue & 0x00ffffff).toUpperCase() : Integer.toString(newValue);
|
||||
String text = hex ? "0x" + ColorUtil.toHex(new Color(newValue)).toUpperCase() : Integer.toString(newValue);
|
||||
expr.replace(factory.createExpressionFromText(text, null));
|
||||
}
|
||||
}
|
||||
|
||||
+13
-1
@@ -1040,7 +1040,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (myRefCountHolder != null) {
|
||||
myRefCountHolder.registerReference(expression, result);
|
||||
}
|
||||
if (result.getElement() != null && !result.isAccessible()) {
|
||||
final PsiElement method = result.getElement();
|
||||
if (method != null && !result.isAccessible()) {
|
||||
final String accessProblem = HighlightUtil.buildProblemWithAccessDescription(expression, result);
|
||||
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(accessProblem).create();
|
||||
myHolder.add(info);
|
||||
@@ -1075,6 +1076,17 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, expression.getTextRange()));
|
||||
}
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
if (method instanceof PsiMethod && ((PsiMethod)method).hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
final PsiElement qualifier = expression.getQualifier();
|
||||
if (qualifier instanceof PsiSuperExpression) {
|
||||
myHolder.add(HighlightInfo
|
||||
.newHighlightInfo(HighlightInfoType.ERROR)
|
||||
.range(expression.getReferenceNameElement())
|
||||
.descriptionAndTooltip("Abstract method '" + ((PsiMethod)method).getName() + "' cannot be accessed directly").create());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+14
@@ -23,6 +23,7 @@ import com.intellij.ide.util.DirectoryChooserUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -43,6 +44,7 @@ import java.util.*;
|
||||
* @author peter
|
||||
*/
|
||||
public class CreateClassOrPackageFix extends LocalQuickFixAndIntentionActionOnPsiElement {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.quickFix.CreateClassOrPackageFix");
|
||||
private final List<PsiDirectory> myWritableDirectoryList;
|
||||
private final String myPresentation;
|
||||
|
||||
@@ -233,9 +235,15 @@ public class CreateClassOrPackageFix extends LocalQuickFixAndIntentionActionOnPs
|
||||
public static List<PsiDirectory> getWritableDirectoryListDefault(@Nullable final PsiPackage context,
|
||||
final GlobalSearchScope scope,
|
||||
final PsiManager psiManager) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Getting writable directory list for package '" + (context == null ? null : context.getQualifiedName()) + "', scope=" + scope);
|
||||
}
|
||||
final List<PsiDirectory> writableDirectoryList = new ArrayList<PsiDirectory>();
|
||||
if (context != null) {
|
||||
for (PsiDirectory directory : context.getDirectories()) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Package directory: " + directory);
|
||||
}
|
||||
if (directory.isWritable() && scope.contains(directory.getVirtualFile())) {
|
||||
writableDirectoryList.add(directory);
|
||||
}
|
||||
@@ -244,11 +252,17 @@ public class CreateClassOrPackageFix extends LocalQuickFixAndIntentionActionOnPs
|
||||
else {
|
||||
for (VirtualFile root : ProjectRootManager.getInstance(psiManager.getProject()).getContentSourceRoots()) {
|
||||
PsiDirectory directory = psiManager.findDirectory(root);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Root: " + root + ", directory: " + directory);
|
||||
}
|
||||
if (directory != null && directory.isWritable() && scope.contains(directory.getVirtualFile())) {
|
||||
writableDirectoryList.add(directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Result " + writableDirectoryList);
|
||||
}
|
||||
return writableDirectoryList;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -431,7 +431,13 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
|
||||
public void updateUI(final Object p, final ParameterInfoUIContext context) {
|
||||
if (p instanceof CandidateInfo) {
|
||||
CandidateInfo info = (CandidateInfo)p;
|
||||
updateMethodPresentation((PsiMethod)info.getElement(), getCandidateInfoSubstitutor(info), context);
|
||||
PsiMethod method = (PsiMethod)info.getElement();
|
||||
if (!method.isValid()) {
|
||||
context.setUIComponentEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
updateMethodPresentation(method, getCandidateInfoSubstitutor(info), context);
|
||||
}
|
||||
else {
|
||||
updateMethodPresentation((PsiMethod)p, null, context);
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.intellij.psi.impl.DebugUtil;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -213,27 +214,29 @@ public class PsiTypeLookupItem extends LookupItem {
|
||||
final PsiClass psiClass = classResolveResult.getElement();
|
||||
|
||||
if (psiClass != null) {
|
||||
final PsiSubstitutor substitutor = classResolveResult.getSubstitutor();
|
||||
String name = psiClass.getName();
|
||||
if (name != null) {
|
||||
final PsiSubstitutor substitutor = classResolveResult.getSubstitutor();
|
||||
|
||||
PsiClass resolved = JavaPsiFacade.getInstance(psiClass.getProject()).getResolveHelper().resolveReferencedClass(psiClass.getName(), context);
|
||||
PsiClass resolved = JavaPsiFacade.getInstance(psiClass.getProject()).getResolveHelper().resolveReferencedClass(name, context);
|
||||
|
||||
Set<String> allStrings = new HashSet<String>();
|
||||
String lookupString = psiClass.getName();
|
||||
allStrings.add(lookupString);
|
||||
if (!psiClass.getManager().areElementsEquivalent(resolved, psiClass) && !PsiUtil.isInnerClass(psiClass)) {
|
||||
// inner class name should be shown qualified if its not accessible by single name
|
||||
PsiClass aClass = psiClass.getContainingClass();
|
||||
while (aClass != null && !PsiUtil.isInnerClass(aClass)) {
|
||||
lookupString = aClass.getName() + '.' + lookupString;
|
||||
allStrings.add(lookupString);
|
||||
aClass = aClass.getContainingClass();
|
||||
Set<String> allStrings = new HashSet<String>();
|
||||
allStrings.add(name);
|
||||
if (!psiClass.getManager().areElementsEquivalent(resolved, psiClass) && !PsiUtil.isInnerClass(psiClass)) {
|
||||
// inner class name should be shown qualified if its not accessible by single name
|
||||
PsiClass aClass = psiClass.getContainingClass();
|
||||
while (aClass != null && !PsiUtil.isInnerClass(aClass)) {
|
||||
name = aClass.getName() + '.' + name;
|
||||
allStrings.add(name);
|
||||
aClass = aClass.getContainingClass();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PsiTypeLookupItem item = new PsiTypeLookupItem(psiClass, lookupString, diamond, bracketsCount, importFixer);
|
||||
item.addLookupStrings(allStrings.toArray(new String[allStrings.size()]));
|
||||
item.setAttribute(SUBSTITUTOR, substitutor);
|
||||
return item;
|
||||
PsiTypeLookupItem item = new PsiTypeLookupItem(psiClass, name, diamond, bracketsCount, importFixer);
|
||||
item.addLookupStrings(ArrayUtil.toStringArray(allStrings));
|
||||
item.setAttribute(SUBSTITUTOR, substitutor);
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class AnnotateMethodFix implements LocalQuickFix {
|
||||
if (annotateOverriddenMethods()) {
|
||||
PsiMethod[] methods = OverridingMethodsSearch.search(method, GlobalSearchScope.allScope(project), true).toArray(PsiMethod.EMPTY_ARRAY);
|
||||
for (PsiMethod psiMethod : methods) {
|
||||
if (!AnnotationUtil.isAnnotated(psiMethod, myAnnotation, false, false) && psiMethod.getManager().isInProject(psiMethod)) {
|
||||
if (AnnotationUtil.isAnnotatingApplicable(psiMethod, myAnnotation) && !AnnotationUtil.isAnnotated(psiMethod, myAnnotation, false, false) && psiMethod.getManager().isInProject(psiMethod)) {
|
||||
toAnnotate.add(psiMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection.dataFlow;
|
||||
|
||||
import com.intellij.codeInsight.*;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.openapi.project.*;
|
||||
import com.intellij.openapi.ui.*;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.components.*;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Dialog that appears when user clicks the "Configure IsNull/IsNotNull/True/False Check/Assertion Methods"
|
||||
* on the Errors dialog for the Constant Conditions Inspection. It is divided into 6 parts
|
||||
* <ol>
|
||||
* <li>Is Null Check MethodsPanel</li>
|
||||
* <li>Is Not Null Check MethodsPanel</li>
|
||||
* <li>Assert Is Null MethodsPanel</li>
|
||||
* <li>Assert Is Not Null MethodsPanel</li>
|
||||
* <li>Assert True MethodsPanel</li>
|
||||
* <li>Assert False MethodsPanel</li>
|
||||
* </ol>
|
||||
*
|
||||
* @author <a href="mailto:johnnyclark@gmail.com">Johnny Clark</a>
|
||||
* Creation Date: 8/3/12
|
||||
*/
|
||||
public class ConditionCheckDialog extends DialogWrapper {
|
||||
private final Project myProject;
|
||||
private final @NotNull Splitter mainSplitter;
|
||||
private final @NotNull MethodsPanel myIsNullCheckMethodPanel;
|
||||
private final @NotNull MethodsPanel myIsNotNullCheckMethodPanel;
|
||||
private final @NotNull MethodsPanel myAssertIsNullMethodPanel;
|
||||
private final @NotNull MethodsPanel myAssertIsNotNullMethodPanel;
|
||||
private final @NotNull MethodsPanel myAssertTrueMethodPanel;
|
||||
private final @NotNull MethodsPanel myAssertFalseMethodPanel;
|
||||
|
||||
public ConditionCheckDialog(Project project, String mainDialogTitle) {
|
||||
super(project, true);
|
||||
myProject = project;
|
||||
|
||||
final ConditionCheckManager manager = ConditionCheckManager.getInstance(myProject);
|
||||
mainSplitter = new Splitter(true, 0.3f);
|
||||
final Splitter topThirdSplitter = new Splitter(false);
|
||||
final Splitter bottomTwoThirdsSplitter = new Splitter(true);
|
||||
final Splitter isNullIsNotNullCheckMethodSplitter = new Splitter(false);
|
||||
final Splitter assertTrueFalseMethodSplitter = new Splitter(false);
|
||||
|
||||
List<ConditionChecker> isNullCheckMethods = new ArrayList<ConditionChecker>(manager.getIsNullCheckMethods());
|
||||
List<ConditionChecker> isNotNullCheckMethods = new ArrayList<ConditionChecker>(manager.getIsNotNullCheckMethods());
|
||||
List<ConditionChecker> assertIsNullMethods = new ArrayList<ConditionChecker>(manager.getAssertIsNullMethods());
|
||||
List<ConditionChecker> assertIsNotNullMethods = new ArrayList<ConditionChecker>(manager.getAssertIsNotNullMethods());
|
||||
List<ConditionChecker> assertTrueMethods = new ArrayList<ConditionChecker>(manager.getAssertTrueMethods());
|
||||
List<ConditionChecker> assertFalseMethods = new ArrayList<ConditionChecker>(manager.getAssertFalseMethods());
|
||||
|
||||
myAssertIsNullMethodPanel = new MethodsPanel(assertIsNullMethods, ConditionChecker.Type.ASSERT_IS_NULL_METHOD, myProject);
|
||||
myAssertIsNotNullMethodPanel = new MethodsPanel(assertIsNotNullMethods, ConditionChecker.Type.ASSERT_IS_NOT_NULL_METHOD, myProject);
|
||||
myIsNullCheckMethodPanel = new MethodsPanel(isNullCheckMethods, ConditionChecker.Type.IS_NULL_METHOD, myProject);
|
||||
myIsNotNullCheckMethodPanel = new MethodsPanel(isNotNullCheckMethods, ConditionChecker.Type.IS_NOT_NULL_METHOD, myProject);
|
||||
myAssertTrueMethodPanel = new MethodsPanel(assertTrueMethods, ConditionChecker.Type.ASSERT_TRUE_METHOD, myProject);
|
||||
myAssertFalseMethodPanel = new MethodsPanel(assertFalseMethods, ConditionChecker.Type.ASSERT_FALSE_METHOD, myProject);
|
||||
|
||||
isNullIsNotNullCheckMethodSplitter.setFirstComponent(myIsNullCheckMethodPanel.getComponent());
|
||||
isNullIsNotNullCheckMethodSplitter.setSecondComponent(myIsNotNullCheckMethodPanel.getComponent());
|
||||
assertTrueFalseMethodSplitter.setFirstComponent(myAssertTrueMethodPanel.getComponent());
|
||||
assertTrueFalseMethodSplitter.setSecondComponent(myAssertFalseMethodPanel.getComponent());
|
||||
|
||||
topThirdSplitter.setFirstComponent(myAssertIsNullMethodPanel.getComponent());
|
||||
topThirdSplitter.setSecondComponent(myAssertIsNotNullMethodPanel.getComponent());
|
||||
bottomTwoThirdsSplitter.setFirstComponent(isNullIsNotNullCheckMethodSplitter);
|
||||
bottomTwoThirdsSplitter.setSecondComponent(assertTrueFalseMethodSplitter);
|
||||
|
||||
mainSplitter.setFirstComponent(topThirdSplitter);
|
||||
mainSplitter.setSecondComponent(bottomTwoThirdsSplitter);
|
||||
|
||||
topThirdSplitter.setPreferredSize(new Dimension(600, 150));
|
||||
bottomTwoThirdsSplitter.setPreferredSize(new Dimension(600, 300));
|
||||
|
||||
myAssertIsNullMethodPanel
|
||||
.setOtherMethodsPanels(myAssertIsNotNullMethodPanel, myIsNullCheckMethodPanel, myIsNotNullCheckMethodPanel, myAssertTrueMethodPanel,
|
||||
myAssertFalseMethodPanel);
|
||||
myAssertIsNotNullMethodPanel
|
||||
.setOtherMethodsPanels(myAssertIsNullMethodPanel, myIsNullCheckMethodPanel, myIsNotNullCheckMethodPanel, myAssertTrueMethodPanel,
|
||||
myAssertFalseMethodPanel);
|
||||
myIsNullCheckMethodPanel
|
||||
.setOtherMethodsPanels(myAssertIsNullMethodPanel, myAssertIsNotNullMethodPanel, myIsNotNullCheckMethodPanel, myAssertTrueMethodPanel,
|
||||
myAssertFalseMethodPanel);
|
||||
myIsNotNullCheckMethodPanel
|
||||
.setOtherMethodsPanels(myAssertIsNullMethodPanel, myAssertIsNotNullMethodPanel, myIsNullCheckMethodPanel, myAssertTrueMethodPanel,
|
||||
myAssertFalseMethodPanel);
|
||||
myAssertTrueMethodPanel
|
||||
.setOtherMethodsPanels(myAssertIsNullMethodPanel, myAssertIsNotNullMethodPanel, myIsNotNullCheckMethodPanel, myIsNullCheckMethodPanel,
|
||||
myAssertFalseMethodPanel);
|
||||
myAssertFalseMethodPanel
|
||||
.setOtherMethodsPanels(myAssertIsNullMethodPanel, myAssertIsNotNullMethodPanel, myIsNotNullCheckMethodPanel, myIsNullCheckMethodPanel,
|
||||
myAssertTrueMethodPanel);
|
||||
|
||||
init();
|
||||
setTitle(mainDialogTitle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return mainSplitter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doOKAction() {
|
||||
final ConditionCheckManager manager = ConditionCheckManager.getInstance(myProject);
|
||||
manager.setIsNotNullCheckMethods(myIsNotNullCheckMethodPanel.getConditionChecker());
|
||||
manager.setIsNullCheckMethods(myIsNullCheckMethodPanel.getConditionChecker());
|
||||
manager.setAssertIsNotNullMethods(myAssertIsNotNullMethodPanel.getConditionChecker());
|
||||
manager.setAssertIsNullMethods(myAssertIsNullMethodPanel.getConditionChecker());
|
||||
manager.setAssertTrueMethods(myAssertTrueMethodPanel.getConditionChecker());
|
||||
manager.setAssertFalseMethods(myAssertFalseMethodPanel.getConditionChecker());
|
||||
|
||||
super.doOKAction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Null, Is Not Null, Assert True and Assert False Method Panel at the top of the main Dialog.
|
||||
*/
|
||||
class MethodsPanel {
|
||||
private final @NotNull JBList myList;
|
||||
private final @NotNull JPanel myPanel;
|
||||
private final @NotNull Project myProject;
|
||||
private Set<MethodsPanel> otherPanels;
|
||||
|
||||
public MethodsPanel(final List<ConditionChecker> checkers, final ConditionChecker.Type type, final @NotNull Project myProject) {
|
||||
this.myProject = myProject;
|
||||
myList = new JBList(new CollectionListModel<ConditionChecker>(checkers));
|
||||
myPanel = new JPanel(new BorderLayout());
|
||||
myPanel.setBorder(IdeBorderFactory.createTitledBorder(initTitle(type), false, new Insets(10, 0, 0, 0)));
|
||||
myPanel.setPreferredSize(new Dimension(400, 150));
|
||||
|
||||
myList.setCellRenderer(new ColoredListCellRenderer() {
|
||||
@Override
|
||||
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
|
||||
String s = value.toString();
|
||||
if (s.contains("*")) {
|
||||
int indexOfAsterix1 = s.indexOf("*");
|
||||
int indexOfAsterix2 = s.lastIndexOf("*");
|
||||
if (indexOfAsterix1 >= 0 &&
|
||||
indexOfAsterix1 < s.length() &&
|
||||
indexOfAsterix2 >= 0 &&
|
||||
indexOfAsterix2 < s.length() &&
|
||||
indexOfAsterix1 < indexOfAsterix2) {
|
||||
append(s.substring(0, indexOfAsterix1), SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
append(s.substring(indexOfAsterix1 + 1, indexOfAsterix2), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
append(s.substring(indexOfAsterix2 + 1), SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
}
|
||||
else {
|
||||
append(s, SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final ToolbarDecorator toolbarDecorator =
|
||||
ToolbarDecorator.createDecorator(myList).disableUpDownActions().setAddAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton anActionButton) {
|
||||
chooseMethod(null, type, myList.getModel().getSize());
|
||||
}
|
||||
}).setRemoveAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton anActionButton) {
|
||||
CollectionListModel model = getCollectionListModel();
|
||||
if (myList.getSelectedIndex() >= 0 && myList.getSelectedIndex() < model.getSize()) {
|
||||
model.remove(myList.getSelectedIndex());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
myList.addMouseListener(new MouseAdapter() {
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() == 2) {
|
||||
int index = myList.locationToIndex(e.getPoint());
|
||||
CollectionListModel<ConditionChecker> model = getCollectionListModel();
|
||||
if (index >= 0 && model.getSize() > index) {
|
||||
chooseMethod(model.getElementAt(index), type, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
final JPanel panel = toolbarDecorator.createPanel();
|
||||
myPanel.add(panel);
|
||||
myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
}
|
||||
|
||||
private String initTitle(@NotNull ConditionChecker.Type type) {
|
||||
if (type.equals(ConditionChecker.Type.IS_NULL_METHOD)) {
|
||||
return InspectionsBundle.message("configure.checker.option.isNull.method.panel.title");
|
||||
}
|
||||
else if (type.equals(ConditionChecker.Type.IS_NOT_NULL_METHOD)) {
|
||||
return InspectionsBundle.message("configure.checker.option.isNotNull.method.panel.title");
|
||||
}
|
||||
else if (type.equals(ConditionChecker.Type.ASSERT_IS_NULL_METHOD)) {
|
||||
return InspectionsBundle.message("configure.checker.option.assert.isNull.method.panel.title");
|
||||
}
|
||||
else if (type.equals(ConditionChecker.Type.ASSERT_IS_NOT_NULL_METHOD)) {
|
||||
return InspectionsBundle.message("configure.checker.option.assert.isNotNull.method.panel.title");
|
||||
}
|
||||
else if (type.equals(ConditionChecker.Type.ASSERT_TRUE_METHOD)) {
|
||||
return InspectionsBundle.message("configure.checker.option.assert.true.method.panel.title");
|
||||
}
|
||||
else if (type.equals(ConditionChecker.Type.ASSERT_FALSE_METHOD)) {
|
||||
return InspectionsBundle.message("configure.checker.option.assert.false.method.panel.title");
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("MethodCheckerDetailsDialog does not support type " + type);
|
||||
}
|
||||
}
|
||||
|
||||
private void chooseMethod(@Nullable ConditionChecker checker, ConditionChecker.Type type, int index) {
|
||||
MethodCheckerDetailsDialog pickMethodPanel =
|
||||
new MethodCheckerDetailsDialog(checker, type, myProject, myPanel, getConditionCheckers(), getOtherCheckers());
|
||||
pickMethodPanel.show();
|
||||
ConditionChecker chk = pickMethodPanel.getConditionChecker();
|
||||
if (chk != null) {
|
||||
CollectionListModel<ConditionChecker> model = getCollectionListModel();
|
||||
if (model.getSize() <= index) {
|
||||
model.add(chk);
|
||||
}
|
||||
else {
|
||||
model.setElementAt(chk, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CollectionListModel<ConditionChecker> getCollectionListModel() {
|
||||
//noinspection unchecked
|
||||
return (CollectionListModel<ConditionChecker>)myList.getModel();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JPanel getComponent() {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
public List<ConditionChecker> getConditionChecker() {
|
||||
CollectionListModel<ConditionChecker> model = getCollectionListModel();
|
||||
return new ArrayList<ConditionChecker>(model.getItems());
|
||||
}
|
||||
|
||||
public Set<ConditionChecker> getConditionCheckers() {
|
||||
Set<ConditionChecker> set = new HashSet<ConditionChecker>();
|
||||
set.addAll(getConditionChecker());
|
||||
return set;
|
||||
}
|
||||
|
||||
public void setOtherMethodsPanels(MethodsPanel p1, MethodsPanel p2, MethodsPanel p3, MethodsPanel p4, MethodsPanel p5) {
|
||||
otherPanels = new HashSet<MethodsPanel>();
|
||||
otherPanels.add(p1);
|
||||
otherPanels.add(p2);
|
||||
otherPanels.add(p3);
|
||||
otherPanels.add(p4);
|
||||
otherPanels.add(p5);
|
||||
}
|
||||
|
||||
public Set<ConditionChecker> getOtherCheckers() {
|
||||
Set<ConditionChecker> otherCheckers = new HashSet<ConditionChecker>();
|
||||
for (MethodsPanel otherPanel : otherPanels) {
|
||||
otherCheckers.addAll(otherPanel.getConditionCheckers());
|
||||
}
|
||||
return otherCheckers;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInspection.dataFlow;
|
||||
|
||||
import com.intellij.codeInsight.ConditionCheckManager;
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.*;
|
||||
import com.intellij.codeInspection.dataFlow.value.*;
|
||||
@@ -1218,7 +1219,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
ConditionalGotoInstruction cond = new ConditionalGotoInstruction(NOT_FOUND, false, null);
|
||||
addInstruction(cond);
|
||||
addInstruction(new EmptyStackInstruction());
|
||||
addInstruction(new PushInstruction(myFactory.getTypeFactory().create(ref), null));
|
||||
addInstruction(new PushInstruction(myFactory.getNotNullFactory().create(ref), null));
|
||||
addThrowCode(ref);
|
||||
cond.setOffset(myCurrentFlow.getInstructionCount());
|
||||
}
|
||||
@@ -1305,7 +1306,8 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if ("junit.framework.Assert".equals(className) || "org.junit.Assert".equals(className) || "org.testng.Assert".equals(className)) {
|
||||
else if ("junit.framework.Assert".equals(className) || "org.junit.Assert".equals(className) ||
|
||||
"junit.framework.TestCase".equals(className) || "org.testng.Assert".equals(className)) {
|
||||
boolean testng = "org.testng.Assert".equals(className);
|
||||
if ("fail".equals(methodName)) {
|
||||
pushParameters(params, false, !testng);
|
||||
@@ -1342,6 +1344,82 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
if (ConditionCheckManager.isCheck(resolved)) {
|
||||
if (ConditionCheckManager.isAssertIsNullCheckMethod(resolved)) {
|
||||
int paramIndex = 0;
|
||||
for (PsiExpression param : params) {
|
||||
param.accept(this);
|
||||
if (ConditionCheckManager.isAssertIsNullCheckMethod(resolved, paramIndex++)) {
|
||||
addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null));
|
||||
addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, expression.getProject()));
|
||||
conditionalExit(exitPoint, false); // Exit if Equal NULL is True
|
||||
} else {
|
||||
addInstruction(new PopInstruction());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (ConditionCheckManager.isAssertIsNotNullCheckMethod(resolved)) {
|
||||
int paramIndex = 0;
|
||||
for (PsiExpression param : params) {
|
||||
param.accept(this);
|
||||
if (ConditionCheckManager.isAssertIsNotNullCheckMethod(resolved, paramIndex++)) {
|
||||
addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null));
|
||||
addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, expression.getProject()));
|
||||
conditionalExit(exitPoint, true); // Exit if NotEqual NULL is True
|
||||
} else {
|
||||
addInstruction(new PopInstruction());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (ConditionCheckManager.isNullCheckMethod(resolved)) {
|
||||
int paramIndex = 0;
|
||||
for (PsiExpression param : params) {
|
||||
param.accept(this);
|
||||
if (ConditionCheckManager.isNullCheckMethod(resolved, paramIndex++)) {
|
||||
addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null));
|
||||
addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, expression.getProject()));
|
||||
} else {
|
||||
addInstruction(new PopInstruction());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (ConditionCheckManager.isNotNullCheckMethod(resolved)) {
|
||||
int paramIndex = 0;
|
||||
for (PsiExpression param : params) {
|
||||
param.accept(this);
|
||||
if (ConditionCheckManager.isNotNullCheckMethod(resolved, paramIndex++)) {
|
||||
addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null));
|
||||
addInstruction(new BinopInstruction(JavaTokenType.NE, null, expression.getProject()));
|
||||
} else {
|
||||
addInstruction(new PopInstruction());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (ConditionCheckManager.isAssertTrueCheckMethod(resolved)) {
|
||||
int paramIndex = 0;
|
||||
for (PsiExpression param : params) {
|
||||
param.accept(this);
|
||||
if (ConditionCheckManager.isAssertTrueCheckMethod(resolved, paramIndex++)) {
|
||||
conditionalExit(exitPoint, false);
|
||||
} else {
|
||||
addInstruction(new PopInstruction());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (ConditionCheckManager.isAssertFalseCheckMethod(resolved)) {
|
||||
int paramIndex = 0;
|
||||
for (PsiExpression param : params) {
|
||||
param.accept(this);
|
||||
if (ConditionCheckManager.isAssertFalseCheckMethod(resolved, paramIndex++)) {
|
||||
conditionalExit(exitPoint, true);
|
||||
} else {
|
||||
addInstruction(new PopInstruction());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Idea project only.
|
||||
if (qualifierExpression != null) {
|
||||
if (qualifierExpression.textMatches("LOG")) {
|
||||
|
||||
@@ -587,6 +587,24 @@ public class DataFlowInspection extends BaseLocalInspectionTool {
|
||||
gc.insets.bottom = 15;
|
||||
add(configureAnnotations, gc);
|
||||
|
||||
final JButton configureCheckAnnotations = new JButton(InspectionsBundle.message("configure.checker.option.button"));
|
||||
configureCheckAnnotations.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(OptionsPanel.this));
|
||||
if (project == null) project = ProjectManager.getInstance().getDefaultProject();
|
||||
final ConditionCheckDialog dialog = new ConditionCheckDialog(project,
|
||||
InspectionsBundle.message("configure.checker.option.main.dialog.title")
|
||||
);
|
||||
dialog.show();
|
||||
}
|
||||
});
|
||||
gc.gridy++;
|
||||
gc.fill = GridBagConstraints.NONE;
|
||||
gc.insets.left = 20;
|
||||
gc.insets.bottom = 15;
|
||||
add(configureCheckAnnotations, gc);
|
||||
|
||||
gc.fill = GridBagConstraints.HORIZONTAL;
|
||||
gc.weighty = 1;
|
||||
gc.insets.left = 0;
|
||||
|
||||
@@ -46,7 +46,7 @@ import java.util.*;
|
||||
|
||||
public class DataFlowRunner {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DataFlowRunner");
|
||||
private static final Key<Integer> TOO_EXPENSIVE_SIZE = Key.create("TOO_EXPENSIVE_SIZE");
|
||||
private static final Key<Integer> TOO_EXPENSIVE_HASH = Key.create("TOO_EXPENSIVE_HASH");
|
||||
public static final long ourTimeLimit = 1000 * 1000 * 1000; //1 sec in nanoseconds
|
||||
|
||||
private Instruction[] myInstructions;
|
||||
@@ -103,14 +103,16 @@ public class DataFlowRunner {
|
||||
myFields = flow.getFields();
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Analyzing code block: " + psiBlock.getText());
|
||||
for (int i = 0; i < myInstructions.length; i++) {
|
||||
Instruction instruction = myInstructions[i];
|
||||
LOG.debug(i + ": " + instruction.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Integer tooExpensiveSize = psiBlock.getUserData(TOO_EXPENSIVE_SIZE);
|
||||
if (tooExpensiveSize != null && tooExpensiveSize == psiBlock.getText().hashCode()) {
|
||||
Integer tooExpensiveHash = psiBlock.getUserData(TOO_EXPENSIVE_HASH);
|
||||
if (tooExpensiveHash != null && tooExpensiveHash == psiBlock.getText().hashCode()) {
|
||||
LOG.debug("Too complex because hasn't changed since being too complex already");
|
||||
return RunnerResult.TOO_COMPLEX;
|
||||
}
|
||||
|
||||
@@ -125,7 +127,8 @@ public class DataFlowRunner {
|
||||
int count = 0;
|
||||
while (!queue.isEmpty()) {
|
||||
if (count % 50 == 0 && !unitTestMode && measurer.isTimeOver()) {
|
||||
psiBlock.putUserData(TOO_EXPENSIVE_SIZE, psiBlock.getText().hashCode());
|
||||
LOG.debug("Too complex because the analysis took too long");
|
||||
psiBlock.putUserData(TOO_EXPENSIVE_HASH, psiBlock.getText().hashCode());
|
||||
return RunnerResult.TOO_COMPLEX;
|
||||
}
|
||||
ProgressManager.checkCanceled();
|
||||
@@ -140,11 +143,14 @@ public class DataFlowRunner {
|
||||
|
||||
if (instruction instanceof BranchingInstruction) {
|
||||
if (!instruction.setMemoryStateProcessed(instructionState.getMemoryState().createCopy())) {
|
||||
LOG.debug("Too complex because too many different possible states");
|
||||
return RunnerResult.TOO_COMPLEX; // Too complex :(
|
||||
}
|
||||
}
|
||||
|
||||
//System.out.println(instructionState);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(instructionState.toString());
|
||||
}
|
||||
|
||||
DfaInstructionState[] after = instruction.accept(this, instructionState.getMemoryState(), visitor);
|
||||
if (after != null) {
|
||||
@@ -160,15 +166,18 @@ public class DataFlowRunner {
|
||||
count++;
|
||||
}
|
||||
|
||||
psiBlock.putUserData(TOO_EXPENSIVE_SIZE, null);
|
||||
psiBlock.putUserData(TOO_EXPENSIVE_HASH, null);
|
||||
LOG.debug("Analysis ok");
|
||||
return RunnerResult.OK;
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e) {
|
||||
LOG.error(psiBlock.getText(), e); /* TODO[max] !!! hack (of 18186). Please fix in better times. */
|
||||
LOG.error(psiBlock.getText(), e); // TODO fix in better times
|
||||
return RunnerResult.ABORTED;
|
||||
}
|
||||
catch (EmptyStackException e) {
|
||||
//LOG.error(psiBlock.getText(), e); /* TODO[max] !!! hack (of 18186). Please fix in better times. */
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.error(e); // TODO fix in better times
|
||||
}
|
||||
return RunnerResult.ABORTED;
|
||||
}
|
||||
}
|
||||
|
||||
+708
@@ -0,0 +1,708 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection.dataFlow;
|
||||
|
||||
import com.intellij.codeInsight.*;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.ide.util.*;
|
||||
import com.intellij.openapi.editor.event.*;
|
||||
import com.intellij.openapi.project.*;
|
||||
import com.intellij.openapi.ui.*;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.*;
|
||||
import com.intellij.ui.*;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.codeInsight.ConditionChecker.Type.*;
|
||||
|
||||
/**
|
||||
* Dialog that appears when the user clicks the Add Button or double clicks a row item in a MethodsPanel. The MethodsPanel is accessed from the ConditionCheckDialog
|
||||
*/
|
||||
class MethodCheckerDetailsDialog extends DialogWrapper implements PropertyChangeListener, ItemListener {
|
||||
private final @NotNull ConditionChecker.Type myType;
|
||||
private final @NotNull Project myProject;
|
||||
private final @NotNull ParameterDropDown parameterDropDown;
|
||||
private final @NotNull MethodDropDown methodDropDown;
|
||||
private final @NotNull ClassField classField;
|
||||
private final @NotNull Set<ConditionChecker> myOtherCheckers;
|
||||
private final @Nullable ConditionChecker myPreviouslySelectedChecker;
|
||||
/**
|
||||
* Set by the OK and/or Cancel actions so that the caller can retrieve it via a call to getMethodIsNullIsNotNullChecker
|
||||
*/
|
||||
private @Nullable ConditionChecker mySelectedChecker;
|
||||
|
||||
MethodCheckerDetailsDialog(@Nullable ConditionChecker previouslySelectedChecker,
|
||||
@NotNull ConditionChecker.Type type,
|
||||
@NotNull Project project,
|
||||
@NotNull Component component,
|
||||
@NotNull Set<ConditionChecker> otherCheckersSameType,
|
||||
@NotNull Set<ConditionChecker> otherCheckers) {
|
||||
super(component, true);
|
||||
if (!isSupported(type)) throw new IllegalArgumentException("Type is invalid " + type);
|
||||
|
||||
myProject = project;
|
||||
myType = type;
|
||||
myOtherCheckers = new HashSet<ConditionChecker>(otherCheckersSameType);
|
||||
myOtherCheckers.addAll(otherCheckers);
|
||||
myPreviouslySelectedChecker = previouslySelectedChecker;
|
||||
if (myPreviouslySelectedChecker != null) myOtherCheckers.remove(myPreviouslySelectedChecker);
|
||||
|
||||
PsiClass psiClass = null;
|
||||
PsiMethod psiMethod = null;
|
||||
PsiParameter psiParameter = null;
|
||||
if (previouslySelectedChecker != null) {
|
||||
psiClass =
|
||||
JavaPsiFacade.getInstance(myProject).findClass(previouslySelectedChecker.getClassName(), GlobalSearchScope.allScope(myProject));
|
||||
if (psiClass != null) {
|
||||
for (PsiMethod method : psiClass.findMethodsByName(previouslySelectedChecker.getMethodName(), true)) {
|
||||
if (previouslySelectedChecker.equals(buildParameterClassListFromPsiMethod(method))) {
|
||||
psiMethod = method;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (psiMethod != null) {
|
||||
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
|
||||
if (parameters.length - 1 >= previouslySelectedChecker.getCheckedParameterIndex()) {
|
||||
psiParameter = parameters[previouslySelectedChecker.getCheckedParameterIndex()];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (psiClass == null || psiMethod == null || psiParameter == null) {
|
||||
psiClass = null;
|
||||
psiMethod = null;
|
||||
psiParameter = null;
|
||||
}
|
||||
|
||||
classField = new ClassField(myProject, psiClass);
|
||||
methodDropDown = new MethodDropDown(psiClass, psiMethod, myType, MethodDropDown.buildModel());
|
||||
parameterDropDown = new ParameterDropDown(psiMethod, psiParameter, ParameterDropDown.buildModel(), myType);
|
||||
classField.addPropertyChangeListener(methodDropDown);
|
||||
classField.addPropertyChangeListener(parameterDropDown);
|
||||
classField.addPropertyChangeListener(this);
|
||||
methodDropDown.addItemListener(parameterDropDown);
|
||||
methodDropDown.addItemListener(this);
|
||||
parameterDropDown.addItemListener(this);
|
||||
init();
|
||||
checkOkActionEnable();
|
||||
setTitle(initTitle(type));
|
||||
}
|
||||
|
||||
private static boolean isSupported(ConditionChecker.Type type) {
|
||||
return type == IS_NULL_METHOD || type == IS_NOT_NULL_METHOD ||
|
||||
type == ASSERT_IS_NULL_METHOD || type == ASSERT_IS_NOT_NULL_METHOD ||
|
||||
type == ASSERT_TRUE_METHOD || type == ASSERT_FALSE_METHOD;
|
||||
}
|
||||
|
||||
private static List<String> buildParameterClassListFromPsiMethod(PsiMethod psiMethod) {
|
||||
List<String> parameterClasses = new ArrayList<String>();
|
||||
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
|
||||
for (PsiParameter param : parameters) {
|
||||
PsiTypeElement typeElement = param.getTypeElement();
|
||||
if (typeElement == null) return new ArrayList<String>();
|
||||
|
||||
PsiType psiType = typeElement.getType();
|
||||
|
||||
parameterClasses.add(psiType.getCanonicalText());
|
||||
}
|
||||
return parameterClasses;
|
||||
}
|
||||
|
||||
private static String initTitle(@NotNull ConditionChecker.Type type) {
|
||||
if (type.equals(IS_NULL_METHOD)) {
|
||||
return InspectionsBundle.message("configure.checker.option.isNull.add.method.checker.dialog.title");
|
||||
}
|
||||
else if (type.equals(IS_NOT_NULL_METHOD)) {
|
||||
return InspectionsBundle.message("configure.checker.option.isNotNull.add.method.checker.dialog.title");
|
||||
}
|
||||
else if (type.equals(ASSERT_IS_NULL_METHOD)) {
|
||||
return InspectionsBundle.message("configure.checker.option.assert.isNull.add.method.checker.dialog.title");
|
||||
}
|
||||
else if (type.equals(ASSERT_IS_NOT_NULL_METHOD)) {
|
||||
return InspectionsBundle.message("configure.checker.option.assert.isNotNull.add.method.checker.dialog.title");
|
||||
}
|
||||
else if (type.equals(ASSERT_TRUE_METHOD)) {
|
||||
return InspectionsBundle.message("configure.checker.option.assert.true.add.method.checker.dialog.title");
|
||||
}
|
||||
else if (type.equals(ASSERT_FALSE_METHOD)) {
|
||||
return InspectionsBundle.message("configure.checker.option.assert.false.add.method.checker.dialog.title");
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("MethodCheckerDetailsDialog does not support type " + type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
final JPanel panel = new JPanel();
|
||||
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
||||
|
||||
final LabeledComponent<ClassField> classComponent = new LabeledComponent<ClassField>();
|
||||
final LabeledComponent<MethodDropDown> methodComponent = new LabeledComponent<MethodDropDown>();
|
||||
final LabeledComponent<ParameterDropDown> parameterComponent = new LabeledComponent<ParameterDropDown>();
|
||||
|
||||
classComponent.setText("Class");
|
||||
methodComponent.setText("Method");
|
||||
parameterComponent.setText("Parameter");
|
||||
|
||||
classComponent.setComponent(classField);
|
||||
methodComponent.setComponent(methodDropDown);
|
||||
parameterComponent.setComponent(parameterDropDown);
|
||||
|
||||
panel.add(classComponent);
|
||||
panel.add(methodComponent);
|
||||
panel.add(parameterComponent);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
ConditionChecker getConditionChecker() {
|
||||
return mySelectedChecker;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ConditionChecker buildConditionChecker() {
|
||||
PsiClass psiClass = classField.getPsiClass();
|
||||
PsiMethod psiMethod = methodDropDown.getSelectedPsiMethod();
|
||||
PsiParameter psiParameter = parameterDropDown.getSelectedPsiParameter();
|
||||
if (psiClass != null && psiMethod != null && psiParameter != null) {
|
||||
return new ConditionChecker.FromPsiBuilder(psiMethod, psiParameter, myType).build();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean overlaps(ConditionChecker thisChecker) {
|
||||
for (ConditionChecker overlappingChecker : myOtherCheckers) {
|
||||
if (thisChecker.overlaps(overlappingChecker)) {
|
||||
Messages.showMessageDialog(myProject, InspectionsBundle.message("configure.checker.option.overlap.error.msg") +
|
||||
" " +
|
||||
overlappingChecker.getConditionCheckType() + " " + overlappingChecker.toString(),
|
||||
InspectionsBundle.message("configure.checker.option.overlap.error.title"), Messages.getErrorIcon());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
checkOkActionEnable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
checkOkActionEnable();
|
||||
}
|
||||
|
||||
private void checkOkActionEnable() {
|
||||
if (classField.getPsiClass() == null ||
|
||||
methodDropDown.getSelectedPsiMethod() == null ||
|
||||
parameterDropDown.getSelectedPsiParameter() == null) {
|
||||
setOKActionEnabled(false);
|
||||
}
|
||||
else {
|
||||
setOKActionEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doOKAction() {
|
||||
ConditionChecker checker = buildConditionChecker();
|
||||
if (checker != null && !overlaps(checker)) {
|
||||
if (checker.equals(myPreviouslySelectedChecker)) {
|
||||
mySelectedChecker = myPreviouslySelectedChecker;
|
||||
}
|
||||
else {
|
||||
mySelectedChecker = checker;
|
||||
}
|
||||
super.doOKAction();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOKActionEnabled() {
|
||||
if (!myOKAction.isEnabled()) return false;
|
||||
PsiClass psiClass = classField.getPsiClass();
|
||||
PsiMethod psiMethod = methodDropDown.getSelectedPsiMethod();
|
||||
PsiParameter psiParameter = parameterDropDown.getSelectedPsiParameter();
|
||||
if (psiClass == null || psiMethod == null || psiParameter == null) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Input Text Field for Class Name
|
||||
*/
|
||||
static class ClassField extends EditorTextFieldWithBrowseButton implements ActionListener, DocumentListener {
|
||||
public static final String PROPERTY_PSICLASS = "ClassField.myPsiClass";
|
||||
private final @NotNull Project myProject;
|
||||
private @Nullable PsiClass myPsiClass;
|
||||
|
||||
public ClassField(@NotNull Project project, @Nullable PsiClass psiClass) {
|
||||
super(project, true, buildVisibilityChecker());
|
||||
myProject = project;
|
||||
myPsiClass = psiClass;
|
||||
setPreferredSize(new Dimension(500, (int)getPreferredSize().getHeight()));
|
||||
if (myPsiClass != null) { //noinspection ConstantConditions
|
||||
setText(myPsiClass.getQualifiedName());
|
||||
}
|
||||
addActionListener(this);
|
||||
getChildComponent().addDocumentListener(this);
|
||||
}
|
||||
|
||||
private static JavaCodeFragment.VisibilityChecker buildVisibilityChecker() {
|
||||
return new JavaCodeFragment.VisibilityChecker() {
|
||||
@Override
|
||||
public Visibility isDeclarationVisible(PsiElement declaration, PsiElement place) {
|
||||
return Visibility.VISIBLE;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject)
|
||||
.createNoInnerClassesScopeChooser("Choose Class", GlobalSearchScope.allScope(myProject), new ClassFilter() {
|
||||
@Override
|
||||
public boolean isAccepted(PsiClass aClass) {
|
||||
return !aClass.isAnnotationType();
|
||||
}
|
||||
}, null);
|
||||
chooser.showDialog();
|
||||
PsiClass psiClass = chooser.getSelected();
|
||||
if (psiClass != null) { //noinspection ConstantConditions
|
||||
setText(chooser.getSelected().getQualifiedName());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiClass getPsiClass() {
|
||||
return myPsiClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeDocumentChange(DocumentEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent event) {
|
||||
String className = event.getDocument().getText();
|
||||
PsiClass psiClass = null;
|
||||
if (className != null) {
|
||||
psiClass = JavaPsiFacade.getInstance(myProject).findClass(className, GlobalSearchScope.allScope(myProject));
|
||||
}
|
||||
|
||||
if (psiClass != null && myPsiClass != null) {
|
||||
if (!psiClass.equals(myPsiClass)) {
|
||||
firePropertyChange(PROPERTY_PSICLASS, myPsiClass, psiClass);
|
||||
myPsiClass = psiClass;
|
||||
}
|
||||
}
|
||||
else if (psiClass != null) {
|
||||
firePropertyChange(PROPERTY_PSICLASS, myPsiClass, psiClass);
|
||||
myPsiClass = psiClass;
|
||||
}
|
||||
else if (myPsiClass != null) {
|
||||
firePropertyChange(PROPERTY_PSICLASS, myPsiClass, psiClass);
|
||||
myPsiClass = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop Down for picking Method Name
|
||||
*/
|
||||
static class MethodDropDown extends JComboBox implements PropertyChangeListener {
|
||||
private final @NotNull ConditionChecker.Type myType;
|
||||
private final @NotNull SortedComboBoxModel<MethodWrapper> myModel;
|
||||
private @Nullable PsiClass myPsiClass;
|
||||
|
||||
MethodDropDown(@Nullable PsiClass psiClass,
|
||||
@Nullable PsiMethod psiMethod,
|
||||
@NotNull ConditionChecker.Type type,
|
||||
@NotNull SortedComboBoxModel<MethodWrapper> model) {
|
||||
super(model);
|
||||
|
||||
if (!isSupported(type)) throw new IllegalArgumentException("Type is invalid " + type);
|
||||
|
||||
myPsiClass = psiClass;
|
||||
myType = type;
|
||||
myModel = model;
|
||||
setEnabled(myPsiClass != null);
|
||||
initValues();
|
||||
if (psiMethod != null) {
|
||||
for (Iterator<MethodWrapper> iterator = myModel.iterator(); iterator.hasNext(); ) {
|
||||
MethodWrapper methodWrapper = iterator.next();
|
||||
if (methodWrapper.getPsiMethod().equals(psiMethod)) {
|
||||
setSelectedItem(methodWrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isMethodFromJavaLangObject(PsiMethod method) {
|
||||
if (method == null) return false;
|
||||
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass == null) return false;
|
||||
String name = containingClass.getQualifiedName();
|
||||
if (name == null) return false;
|
||||
|
||||
if (CommonClassNames.JAVA_LANG_OBJECT.equals(name)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SortedComboBoxModel<MethodWrapper> buildModel() {
|
||||
return new SortedComboBoxModel<MethodWrapper>(new Comparator<MethodWrapper>() {
|
||||
@Override
|
||||
public int compare(MethodWrapper o1, MethodWrapper o2) {
|
||||
return o1.compareTo(o2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initValues() {
|
||||
if (myPsiClass != null) {
|
||||
myModel.clear();
|
||||
myModel.setSelectedItem(null);
|
||||
PsiMethod[] allMethods = myPsiClass.getAllMethods();
|
||||
for (PsiMethod method : allMethods) {
|
||||
MethodWrapper methodWrapper = new MethodWrapper(method);
|
||||
if (qualifies(method) && !myModel.getItems().contains(methodWrapper)) myModel.add(methodWrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean qualifies(PsiMethod psiMethod) {
|
||||
if (isMethodFromJavaLangObject(psiMethod)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
|
||||
if (parameters.length < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (myType == IS_NULL_METHOD || myType == IS_NOT_NULL_METHOD) {
|
||||
PsiType returnType = psiMethod.getReturnType();
|
||||
if (returnType != PsiType.BOOLEAN && (returnType == null || !returnType.getCanonicalText().equals(Boolean.class.toString()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (myType == ASSERT_TRUE_METHOD || myType == ASSERT_FALSE_METHOD) {
|
||||
boolean booleanParamExists = false;
|
||||
for (PsiParameter psiParameter : parameters) {
|
||||
PsiType type = psiParameter.getType();
|
||||
if (type.equals(PsiType.BOOLEAN) || type.getCanonicalText().equals(Boolean.class.toString())) {
|
||||
booleanParamExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!booleanParamExists) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Else it's ASSERT_IS_NULL_METHOD or ASSERT_IS_NOT_NULL_METHOD.
|
||||
// In that case there is no additional validation
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when ClassField is set and when user selects entry in the MethodDropDown
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getPropertyName().equals(ClassField.PROPERTY_PSICLASS)) {
|
||||
if (evt.getNewValue() == null) {
|
||||
clear();
|
||||
}
|
||||
else {
|
||||
setEnabled(true);
|
||||
if (myPsiClass == null || !myPsiClass.equals(evt.getNewValue())) { // ClassChanged so refresh list
|
||||
myPsiClass = (PsiClass)evt.getNewValue();
|
||||
initValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
myModel.clear();
|
||||
myModel.setSelectedItem(null);
|
||||
setEnabled(false);
|
||||
myPsiClass = null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiMethod getSelectedPsiMethod() {
|
||||
MethodWrapper methodWrapper = myModel.getSelectedItem();
|
||||
if (methodWrapper == null) return null;
|
||||
|
||||
return methodWrapper.getPsiMethod();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop Down for picking Parameter Name
|
||||
*/
|
||||
static class ParameterDropDown extends JComboBox implements PropertyChangeListener, ItemListener {
|
||||
private final @NotNull SortedComboBoxModel<ParameterWrapper> myModel;
|
||||
private final @NotNull ConditionChecker.Type myType;
|
||||
private @Nullable PsiMethod myPsiMethod;
|
||||
|
||||
public ParameterDropDown(@Nullable PsiMethod psiMethod,
|
||||
@Nullable PsiParameter psiParameter,
|
||||
@NotNull SortedComboBoxModel<ParameterWrapper> model,
|
||||
@NotNull ConditionChecker.Type type) {
|
||||
super(model);
|
||||
|
||||
if (!isSupported(type)) throw new IllegalArgumentException("Type is invalid " + type);
|
||||
|
||||
myPsiMethod = psiMethod;
|
||||
myModel = model;
|
||||
myType = type;
|
||||
|
||||
if (myPsiMethod != null) {
|
||||
setEnabled(true);
|
||||
myModel.addAll(getParameterWrappers());
|
||||
if (psiParameter != null) {
|
||||
for (Iterator iterator = myModel.iterator(); iterator.hasNext(); ) {
|
||||
ParameterWrapper wrapper = (ParameterWrapper)iterator.next();
|
||||
if (wrapper.getPsiParameter().equals(psiParameter)) setSelectedItem(wrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
public static SortedComboBoxModel<ParameterWrapper> buildModel() {
|
||||
return new SortedComboBoxModel<ParameterWrapper>(new Comparator<ParameterWrapper>() {
|
||||
@Override
|
||||
public int compare(ParameterWrapper o1, ParameterWrapper o2) {
|
||||
return o1.compareTo(o2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
List<ParameterWrapper> getParameterWrappers() {
|
||||
List<ParameterWrapper> wrappers = new ArrayList<ParameterWrapper>();
|
||||
if (myPsiMethod != null) {
|
||||
PsiParameterList parameterList = myPsiMethod.getParameterList();
|
||||
for (int i = 0; i < parameterList.getParameters().length; i++) {
|
||||
PsiParameter psiParameter = parameterList.getParameters()[i];
|
||||
if (myType == ASSERT_TRUE_METHOD || myType == ASSERT_FALSE_METHOD) {
|
||||
PsiType type = psiParameter.getType();
|
||||
if (type.equals(PsiType.BOOLEAN) || type.getCanonicalText().equals(Boolean.class.toString())) {
|
||||
wrappers.add(new ParameterWrapper(psiParameter, i));
|
||||
}
|
||||
}
|
||||
else {
|
||||
wrappers.add(new ParameterWrapper(psiParameter, i));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return wrappers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getSource() instanceof MethodDropDown) { // The MethodDropDown has changed.
|
||||
MethodDropDown methodDropDown = (MethodDropDown)e.getSource();
|
||||
if (methodDropDown.getSelectedPsiMethod() != null) {
|
||||
setEnabled(true);
|
||||
if (myPsiMethod == null || !myPsiMethod.equals(methodDropDown.getSelectedPsiMethod())) {
|
||||
myPsiMethod = methodDropDown.getSelectedPsiMethod();
|
||||
myModel.clear();
|
||||
myModel.addAll(getParameterWrappers());
|
||||
myModel.setSelectedItem(null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myPsiMethod = null;
|
||||
myModel.clear();
|
||||
myModel.setSelectedItem(null);
|
||||
setEnabled(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new RuntimeException("Unexpected Configuration ParameterDropDown is only expected to receive events from MethodDropDown.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getPropertyName().equals(ClassField.PROPERTY_PSICLASS)) {
|
||||
if (evt.getNewValue() == null) {
|
||||
setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiParameter getSelectedPsiParameter() {
|
||||
ParameterWrapper parameterWrapper = myModel.getSelectedItem();
|
||||
if (parameterWrapper == null) return null;
|
||||
|
||||
return parameterWrapper.getPsiParameter();
|
||||
}
|
||||
|
||||
class ParameterWrapper implements Comparable<ParameterWrapper> {
|
||||
private final @NotNull String id;
|
||||
private final @NotNull PsiParameter psiParameter;
|
||||
private final int index;
|
||||
|
||||
ParameterWrapper(@NotNull PsiParameter psiParameter, int index) {
|
||||
this.psiParameter = psiParameter;
|
||||
this.index = index;
|
||||
String typeName;
|
||||
PsiTypeElement typeElement = psiParameter.getTypeElement();
|
||||
if (typeElement == null) {
|
||||
typeName = "";
|
||||
}
|
||||
else {
|
||||
if (typeElement.getType() instanceof PsiPrimitiveType) {
|
||||
typeName = ((PsiPrimitiveType)typeElement.getType()).getBoxedTypeName();
|
||||
}
|
||||
else {
|
||||
typeName = typeElement.getType().getCanonicalText();
|
||||
}
|
||||
}
|
||||
|
||||
id = typeName + " " + psiParameter.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ParameterWrapper o) {
|
||||
return index - o.index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiParameter getPsiParameter() {
|
||||
return psiParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MethodWrapper implements Comparable<MethodWrapper> {
|
||||
private final @NotNull PsiMethod myPsiMethod;
|
||||
private final @NotNull String myId;
|
||||
|
||||
MethodWrapper(@NotNull PsiMethod psiMethod) {
|
||||
this.myPsiMethod = psiMethod;
|
||||
|
||||
List<String> parameterClassNames = new ArrayList<String>();
|
||||
PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
|
||||
for (PsiParameter psiParameter : parameters) {
|
||||
parameterClassNames.add(getParameterQualifiedName(psiParameter));
|
||||
}
|
||||
|
||||
myId = initId(psiMethod.getName(), parameterClassNames);
|
||||
}
|
||||
|
||||
private static String getParameterQualifiedName(PsiParameter psiParameter) {
|
||||
PsiTypeElement typeElement = psiParameter.getTypeElement();
|
||||
if (typeElement == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (typeElement.getType() instanceof PsiPrimitiveType) {
|
||||
return ((PsiPrimitiveType)typeElement.getType()).getBoxedTypeName();
|
||||
}
|
||||
|
||||
return typeElement.getType().getCanonicalText();
|
||||
}
|
||||
|
||||
private static String initId(String methodName, List<String> parameterNames) {
|
||||
String shortName = methodName + "(";
|
||||
for (String parameterName : parameterNames) {
|
||||
if (parameterNames.lastIndexOf(".") > -1) {
|
||||
shortName += parameterName.substring(parameterName.lastIndexOf(".") + 1) + ", ";
|
||||
}
|
||||
else {
|
||||
shortName += parameterName + ", ";
|
||||
}
|
||||
}
|
||||
|
||||
if (parameterNames.size() > 0) shortName = shortName.substring(0, shortName.lastIndexOf(", "));
|
||||
|
||||
shortName += ")";
|
||||
return shortName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiMethod getPsiMethod() {
|
||||
return myPsiMethod;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getId() {
|
||||
return myId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
MethodWrapper that = (MethodWrapper)o;
|
||||
|
||||
if (!myId.equals(that.myId)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return myId.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MethodWrapper o) {
|
||||
return myId.compareTo(o.myId);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-4
@@ -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.
|
||||
@@ -33,7 +33,6 @@ import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.PatchedSoftReference;
|
||||
import com.intellij.util.containers.ConcurrentHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -82,7 +81,7 @@ public class MethodBodyChecker {
|
||||
SoftReference<Map<String, PsiMethod>> ref = aClass.getUserData(CACHE_KEY);
|
||||
Map<String, PsiMethod> cache = ref == null ? null : ref.get();
|
||||
if (cache == null) {
|
||||
aClass.putUserData(CACHE_KEY, new PatchedSoftReference<Map<String, PsiMethod>>(cache = new ConcurrentHashMap<String, PsiMethod>()));
|
||||
aClass.putUserData(CACHE_KEY, new SoftReference<Map<String, PsiMethod>>(cache = new ConcurrentHashMap<String, PsiMethod>()));
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
@@ -107,7 +106,7 @@ public class MethodBodyChecker {
|
||||
|
||||
if (PsiEquivalenceUtil.areElementsEquivalent(body, templateBody, new Comparator<PsiElement>(){
|
||||
public int compare(final PsiElement element1, final PsiElement element2) {
|
||||
// templates may be different on super method name
|
||||
// templates may be different on super method name
|
||||
if (element1 == superMethod && (element2 == templateMethod || element2 == null)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection.deprecation;
|
||||
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.PsiModifierListImpl;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
// todo[r.sh] drop this after transition period finished
|
||||
public class DeprecatedDefenderSyntaxInspection extends BaseJavaLocalInspectionTool {
|
||||
private final LocalQuickFix myQuickFix = new MyQuickFix();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ProblemDescriptor[] checkMethod(@NotNull PsiMethod method, @NotNull InspectionManager manager, boolean isOnTheFly) {
|
||||
final PsiJavaToken marker = PsiModifierListImpl.findExtensionMethodMarker(method);
|
||||
return marker == null ? null : new ProblemDescriptor[]{
|
||||
manager.createProblemDescriptor(marker, getDisplayName(), myQuickFix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly)
|
||||
};
|
||||
}
|
||||
|
||||
private static class MyQuickFix implements LocalQuickFix {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return InspectionsBundle.message("deprecated.defender.syntax.fix");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
final PsiElement marker = descriptor.getPsiElement();
|
||||
if (marker != null && PsiUtil.isJavaToken(marker, JavaTokenType.DEFAULT_KEYWORD)) {
|
||||
final PsiElement parent = marker.getParent();
|
||||
if (parent instanceof PsiMethod) {
|
||||
marker.delete();
|
||||
final PsiMethod method = (PsiMethod)parent;
|
||||
if (!method.hasModifierProperty(PsiModifier.DEFAULT)) {
|
||||
PsiUtil.setModifierProperty(method, PsiModifier.DEFAULT, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -81,7 +81,9 @@ public class AnnotateOverriddenMethodParameterFix implements LocalQuickFix {
|
||||
for (PsiParameter psiParam : toAnnotate) {
|
||||
try {
|
||||
assert psiParam != null : toAnnotate;
|
||||
new AddAnnotationFix(myAnnotation, psiParam, myAnnosToRemove).invoke(project, null, psiParam.getContainingFile());
|
||||
if (AnnotationUtil.isAnnotatingApplicable(psiParam, myAnnotation)) {
|
||||
new AddAnnotationFix(myAnnotation, psiParam, myAnnosToRemove).invoke(project, null, psiParam.getContainingFile());
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
|
||||
+66
@@ -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 com.intellij.codeInspection.nullable;
|
||||
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 2/22/13
|
||||
*/
|
||||
class ChangeNullableDefaultsFix implements LocalQuickFix {
|
||||
private final NullableNotNullManager myManager;
|
||||
private final String myNotNullName;
|
||||
private final String myNullableName;
|
||||
|
||||
public ChangeNullableDefaultsFix(PsiAnnotation notNull, PsiAnnotation nullable, NullableNotNullManager manager) {
|
||||
myNotNullName = notNull != null ? notNull.getQualifiedName() : null;
|
||||
myNullableName = nullable != null ? nullable.getQualifiedName() : null;
|
||||
myManager = manager;
|
||||
}
|
||||
|
||||
ChangeNullableDefaultsFix(String notNull, String nullable, NullableNotNullManager manager) {
|
||||
myManager = manager;
|
||||
myNotNullName = notNull;
|
||||
myNullableName = nullable;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Make \"" + (myNotNullName != null ? myNotNullName : myNullableName) + "\" default annotation";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
if (myNotNullName != null) {
|
||||
myManager.setDefaultNotNull(myNotNullName);
|
||||
} else {
|
||||
myManager.setDefaultNullable(myNullableName);
|
||||
}
|
||||
}
|
||||
}
|
||||
+46
-6
@@ -85,6 +85,14 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
final String anno = annotated.isDeclaredNotNull ? manager.getDefaultNotNull() : manager.getDefaultNullable();
|
||||
final List<String> annoToRemove = annotated.isDeclaredNotNull ? manager.getNullables() : manager.getNotNulls();
|
||||
|
||||
if (!AnnotationUtil.isAnnotatingApplicable(field, anno)) {
|
||||
final PsiAnnotation notNull = AnnotationUtil.findAnnotation(field, manager.getNotNulls());
|
||||
final PsiAnnotation nullable = AnnotationUtil.findAnnotation(field, manager.getNullables());
|
||||
holder.registerProblem(field.getNameIdentifier(), "Nullable/NotNull defaults are not accessible in current context",
|
||||
new ChangeNullableDefaultsFix(notNull, nullable, manager));
|
||||
return;
|
||||
}
|
||||
|
||||
String propName = JavaCodeStyleManager.getInstance(project).variableNameToPropertyName(field.getName(), VariableKind.FIELD);
|
||||
final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
|
||||
final PsiMethod getter = PropertyUtil.findPropertyGetter(field.getContainingClass(), propName, isStatic, false);
|
||||
@@ -289,9 +297,13 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
reported_not_annotated_method_overrides_notnull = true;
|
||||
final String defaultNotNull = nullableManager.getDefaultNotNull();
|
||||
final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables());
|
||||
final LocalQuickFix fix = AnnotationUtil.isAnnotatingApplicable(method, defaultNotNull)
|
||||
? createAnnotateMethodFix(defaultNotNull, annotationsToRemove)
|
||||
: createChangeDefaultNotNullFix(nullableManager, superMethod);
|
||||
holder.registerProblem(method.getNameIdentifier(),
|
||||
InspectionsBundle.message("inspection.nullable.problems.method.overrides.NotNull"),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, createAnnotateMethodFix(defaultNotNull, annotationsToRemove));
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
wrapFix(fix));
|
||||
}
|
||||
if (REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE || REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL) {
|
||||
PsiParameter[] superParameters = superMethod.getParameterList().getParameters();
|
||||
@@ -313,10 +325,13 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
if (!AnnotationUtil.isAnnotated(parameter, nullableManager.getAllAnnotations(), false, false) &&
|
||||
nullableManager.isNotNull(superParameter, false)) {
|
||||
reported_not_annotated_parameter_overrides_notnull[i] = true;
|
||||
final LocalQuickFix fix = AnnotationUtil.isAnnotatingApplicable(parameter, nullableManager.getDefaultNotNull())
|
||||
? new AddNotNullAnnotationFix(parameter)
|
||||
: createChangeDefaultNotNullFix(nullableManager, superParameter);
|
||||
holder.registerProblem(parameter.getNameIdentifier(),
|
||||
InspectionsBundle.message("inspection.nullable.problems.parameter.overrides.NotNull"),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
new AddNotNullAnnotationFix(parameter));
|
||||
wrapFix(fix));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,22 +349,34 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
}
|
||||
if (hasAnnotatedParameter || annotated.isDeclaredNotNull) {
|
||||
PsiManager manager = method.getManager();
|
||||
final String defaultNotNull = nullableManager.getDefaultNotNull();
|
||||
final boolean superMethodApplicable = AnnotationUtil.isAnnotatingApplicable(method, defaultNotNull);
|
||||
PsiMethod[] overridings =
|
||||
OverridingMethodsSearch.search(method, GlobalSearchScope.allScope(manager.getProject()), true).toArray(PsiMethod.EMPTY_ARRAY);
|
||||
boolean methodQuickFixSuggested = false;
|
||||
for (PsiMethod overriding : overridings) {
|
||||
if (!manager.isInProject(overriding)) continue;
|
||||
|
||||
final boolean applicable = AnnotationUtil.isAnnotatingApplicable(overriding, defaultNotNull);
|
||||
if (!methodQuickFixSuggested
|
||||
&& annotated.isDeclaredNotNull
|
||||
&& !nullableManager.isNotNull(overriding, false)
|
||||
&& (nullableManager.isNullable(overriding, false) || !nullableManager.isNullable(overriding, true))) {
|
||||
method.getNameIdentifier(); //load tree
|
||||
PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, nullableManager.getNotNulls());
|
||||
final String defaultNotNull = nullableManager.getDefaultNotNull();
|
||||
PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, nullableManager.getNotNulls());
|
||||
final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables());
|
||||
|
||||
final LocalQuickFix fix;
|
||||
if (applicable) {
|
||||
fix = new MyAnnotateMethodFix(defaultNotNull, annotationsToRemove);
|
||||
}
|
||||
else {
|
||||
fix = superMethodApplicable ? null : createChangeDefaultNotNullFix(nullableManager, method);
|
||||
}
|
||||
|
||||
holder.registerProblem(annotation, InspectionsBundle.message("nullable.stuff.problems.overridden.methods.are.not.annotated"),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
new MyAnnotateMethodFix(defaultNotNull, annotationsToRemove));
|
||||
wrapFix(fix));
|
||||
methodQuickFixSuggested = true;
|
||||
}
|
||||
if (hasAnnotatedParameter) {
|
||||
@@ -363,7 +390,7 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
holder.registerProblem(annotation,
|
||||
InspectionsBundle.message("nullable.stuff.problems.overridden.method.parameters.are.not.annotated"),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
new AnnotateOverriddenMethodParameterFix(nullableManager.getDefaultNotNull(), nullableManager.getDefaultNullable()));
|
||||
wrapFix(!applicable ? createChangeDefaultNotNullFix(nullableManager, parameters[i]) : new AnnotateOverriddenMethodParameterFix(defaultNotNull, nullableManager.getDefaultNullable())));
|
||||
parameterQuickFixSuggested[i] = true;
|
||||
}
|
||||
}
|
||||
@@ -373,6 +400,19 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
}
|
||||
}
|
||||
|
||||
private static LocalQuickFix[] wrapFix(LocalQuickFix fix) {
|
||||
if (fix == null) return LocalQuickFix.EMPTY_ARRAY;
|
||||
return new LocalQuickFix[]{fix};
|
||||
}
|
||||
|
||||
private static LocalQuickFix createChangeDefaultNotNullFix(NullableNotNullManager nullableManager, PsiModifierListOwner modifierListOwner) {
|
||||
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(modifierListOwner, nullableManager.getNotNulls());
|
||||
if (annotation != null) {
|
||||
return new ChangeNullableDefaultsFix(annotation.getQualifiedName(), null, nullableManager);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected AnnotateMethodFix createAnnotateMethodFix(final String defaultNotNull, final String[] annotationsToRemove) {
|
||||
return new AnnotateMethodFix(defaultNotNull, annotationsToRemove);
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ public class PackageUtil {
|
||||
}
|
||||
|
||||
if (psiDirectory == null) {
|
||||
if (!checkSourceRootsConfigured(module)) return null;
|
||||
if (!checkSourceRootsConfigured(module, askUserToCreate)) return null;
|
||||
final VirtualFile[] sourceRoots = ModuleRootManager.getInstance(module).getSourceRoots();
|
||||
List<PsiDirectory> directoryList = new ArrayList<PsiDirectory>();
|
||||
for (VirtualFile sourceRoot : sourceRoots) {
|
||||
@@ -355,15 +355,22 @@ public class PackageUtil {
|
||||
}
|
||||
|
||||
public static boolean checkSourceRootsConfigured(final Module module) {
|
||||
return checkSourceRootsConfigured(module, true);
|
||||
}
|
||||
|
||||
public static boolean checkSourceRootsConfigured(final Module module, final boolean askUserToSetupSourceRoots) {
|
||||
VirtualFile[] sourceRoots = ModuleRootManager.getInstance(module).getSourceRoots();
|
||||
if (sourceRoots.length == 0) {
|
||||
Messages.showErrorDialog(
|
||||
module.getProject(),
|
||||
ProjectBundle.message("module.source.roots.not.configured.error", module.getName()),
|
||||
ProjectBundle.message("module.source.roots.not.configured.title")
|
||||
);
|
||||
if (!askUserToSetupSourceRoots) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ProjectSettingsService.getInstance(module.getProject()).showModuleConfigurationDialog(module.getName(), CommonContentEntriesEditor.NAME);
|
||||
Project project = module.getProject();
|
||||
Messages.showErrorDialog(project,
|
||||
ProjectBundle.message("module.source.roots.not.configured.error", module.getName()),
|
||||
ProjectBundle.message("module.source.roots.not.configured.title"));
|
||||
|
||||
ProjectSettingsService.getInstance(project).showModuleConfigurationDialog(module.getName(), CommonContentEntriesEditor.NAME);
|
||||
|
||||
sourceRoots = ModuleRootManager.getInstance(module).getSourceRoots();
|
||||
if (sourceRoots.length == 0) {
|
||||
|
||||
@@ -60,7 +60,7 @@ public class TreeJavaClassChooserDialog extends AbstractTreeClassChooserDialog<P
|
||||
@Nullable ClassFilter classFilter,
|
||||
PsiClass baseClass,
|
||||
@Nullable PsiClass initialClass, boolean isShowMembers) {
|
||||
super(title, project, scope, PsiClass.class, createFilter(classFilter), baseClass, initialClass, isShowMembers);
|
||||
super(title, project, scope, PsiClass.class, createFilter(classFilter), baseClass, initialClass, isShowMembers, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -60,7 +60,7 @@ public class BasePackageParameterFactory extends ProjectTemplateParameterFactory
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "Base package:";
|
||||
return "Base \u001Bpackage:";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -195,11 +195,15 @@ public class JavaPsiImplementationHelperImpl extends JavaPsiImplementationHelper
|
||||
if (anchor != null && anchor != aClass) {
|
||||
anchor = anchor.getNextSibling();
|
||||
while (anchor instanceof PsiJavaToken && (anchor.getText().equals(",") || anchor.getText().equals(";"))) {
|
||||
final boolean afterComma = anchor.getText().equals(",");
|
||||
anchor = anchor.getNextSibling();
|
||||
if (afterComma) {
|
||||
newAnchor = skipWhitespaces(aClass, anchor);
|
||||
if (newAnchor != null) return newAnchor;
|
||||
}
|
||||
}
|
||||
if (anchor != null) {
|
||||
newAnchor = skipWhitespaces(aClass, anchor);
|
||||
return newAnchor != null ? newAnchor : anchor;
|
||||
return anchor;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,63 +78,10 @@ public class ImportHelper{
|
||||
}
|
||||
});
|
||||
|
||||
int[] entryForName = ArrayUtil.newIntArray(names.size());
|
||||
PackageEntry[] entries = mySettings.IMPORT_LAYOUT_TABLE.getEntries();
|
||||
for(int i = 0; i < names.size(); i++){
|
||||
Pair<String, Boolean> pair = names.get(i);
|
||||
String packageName = pair.getFirst();
|
||||
Boolean isStatic = pair.getSecond();
|
||||
entryForName[i] = findEntryIndex(packageName, isStatic, entries);
|
||||
}
|
||||
|
||||
List<Pair<String, Boolean>> resultList = new ArrayList<Pair<String, Boolean>>(names.size());
|
||||
for(int i = 0; i < entries.length; i++){
|
||||
for(int j = 0; j < names.size(); j++){
|
||||
if (entryForName[j] == i){
|
||||
resultList.add(names.get(j));
|
||||
names.set(j, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Pair<String, Boolean> name : names) {
|
||||
if (name != null) resultList.add(name);
|
||||
}
|
||||
|
||||
TObjectIntHashMap<String> packageToCountMap = new TObjectIntHashMap<String>();
|
||||
TObjectIntHashMap<String> classToCountMap = new TObjectIntHashMap<String>();
|
||||
for (Pair<String, Boolean> pair : resultList) {
|
||||
String name = pair.getFirst();
|
||||
Boolean isStatic = pair.getSecond();
|
||||
String packageOrClassName = getPackageOrClassName(name);
|
||||
if (packageOrClassName.length() == 0) continue;
|
||||
if (isStatic) {
|
||||
int count = classToCountMap.get(packageOrClassName);
|
||||
classToCountMap.put(packageOrClassName, count + 1);
|
||||
}
|
||||
else {
|
||||
int count = packageToCountMap.get(packageOrClassName);
|
||||
packageToCountMap.put(packageOrClassName, count + 1);
|
||||
}
|
||||
}
|
||||
List<Pair<String, Boolean>> resultList = sortItemsAccordingToSettings(names, mySettings);
|
||||
|
||||
final Set<String> classesOrPackagesToImportOnDemand = new THashSet<String>();
|
||||
class MyVisitorProcedure implements TObjectIntProcedure<String> {
|
||||
private final boolean myIsVisitingPackages;
|
||||
|
||||
MyVisitorProcedure(boolean isVisitingPackages) {
|
||||
myIsVisitingPackages = isVisitingPackages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(final String packageOrClassName, final int count) {
|
||||
if (isToUseImportOnDemand(packageOrClassName, count, !myIsVisitingPackages)){
|
||||
classesOrPackagesToImportOnDemand.add(packageOrClassName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
classToCountMap.forEachEntry(new MyVisitorProcedure(false));
|
||||
packageToCountMap.forEachEntry(new MyVisitorProcedure(true));
|
||||
collectOnDemandImports(resultList, classesOrPackagesToImportOnDemand, ImportHelper.this.mySettings);
|
||||
|
||||
Set<String> classesToUseSingle = findSingleImports(file, resultList, classesOrPackagesToImportOnDemand);
|
||||
Set<String> toReimport = new THashSet<String>();
|
||||
@@ -176,6 +123,71 @@ public class ImportHelper{
|
||||
}
|
||||
}
|
||||
|
||||
public static void collectOnDemandImports(List<Pair<String, Boolean>> resultList,
|
||||
final Set<String> classesOrPackagesToImportOnDemand,
|
||||
final CodeStyleSettings settings) {
|
||||
TObjectIntHashMap<String> packageToCountMap = new TObjectIntHashMap<String>();
|
||||
TObjectIntHashMap<String> classToCountMap = new TObjectIntHashMap<String>();
|
||||
for (Pair<String, Boolean> pair : resultList) {
|
||||
String name = pair.getFirst();
|
||||
Boolean isStatic = pair.getSecond();
|
||||
String packageOrClassName = getPackageOrClassName(name);
|
||||
if (packageOrClassName.length() == 0) continue;
|
||||
if (isStatic) {
|
||||
int count = classToCountMap.get(packageOrClassName);
|
||||
classToCountMap.put(packageOrClassName, count + 1);
|
||||
}
|
||||
else {
|
||||
int count = packageToCountMap.get(packageOrClassName);
|
||||
packageToCountMap.put(packageOrClassName, count + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MyVisitorProcedure implements TObjectIntProcedure<String> {
|
||||
private final boolean myIsVisitingPackages;
|
||||
|
||||
MyVisitorProcedure(boolean isVisitingPackages) {
|
||||
myIsVisitingPackages = isVisitingPackages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(final String packageOrClassName, final int count) {
|
||||
if (isToUseImportOnDemand(packageOrClassName, count, !myIsVisitingPackages, settings)){
|
||||
classesOrPackagesToImportOnDemand.add(packageOrClassName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
classToCountMap.forEachEntry(new MyVisitorProcedure(false));
|
||||
packageToCountMap.forEachEntry(new MyVisitorProcedure(true));
|
||||
}
|
||||
|
||||
public static List<Pair<String, Boolean>> sortItemsAccordingToSettings(List<Pair<String, Boolean>> names, final CodeStyleSettings settings) {
|
||||
int[] entryForName = ArrayUtil.newIntArray(names.size());
|
||||
PackageEntry[] entries = settings.IMPORT_LAYOUT_TABLE.getEntries();
|
||||
for(int i = 0; i < names.size(); i++){
|
||||
Pair<String, Boolean> pair = names.get(i);
|
||||
String packageName = pair.getFirst();
|
||||
Boolean isStatic = pair.getSecond();
|
||||
entryForName[i] = findEntryIndex(packageName, isStatic, entries);
|
||||
}
|
||||
|
||||
List<Pair<String, Boolean>> resultList = new ArrayList<Pair<String, Boolean>>(names.size());
|
||||
for(int i = 0; i < entries.length; i++){
|
||||
for(int j = 0; j < names.size(); j++){
|
||||
if (entryForName[j] == i){
|
||||
resultList.add(names.get(j));
|
||||
names.set(j, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Pair<String, Boolean> name : names) {
|
||||
if (name != null) resultList.add(name);
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<String> findSingleImports(@NotNull final PsiJavaFile file,
|
||||
@NotNull List<Pair<String,Boolean>> names,
|
||||
@@ -620,13 +632,16 @@ public class ImportHelper{
|
||||
return maxSpace;
|
||||
}
|
||||
|
||||
private boolean isToUseImportOnDemand(@NotNull String packageName, int classCount, boolean isStaticImportNeeded){
|
||||
if (!mySettings.USE_SINGLE_CLASS_IMPORTS) return true;
|
||||
int limitCount = isStaticImportNeeded ? mySettings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND :
|
||||
mySettings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND;
|
||||
private static boolean isToUseImportOnDemand(@NotNull String packageName,
|
||||
int classCount,
|
||||
boolean isStaticImportNeeded,
|
||||
final CodeStyleSettings settings){
|
||||
if (!settings.USE_SINGLE_CLASS_IMPORTS) return true;
|
||||
int limitCount = isStaticImportNeeded ? settings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND :
|
||||
settings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND;
|
||||
if (classCount >= limitCount) return true;
|
||||
if (packageName.length() == 0) return false;
|
||||
PackageEntryTable table = mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND;
|
||||
PackageEntryTable table = settings.PACKAGES_TO_USE_IMPORT_ON_DEMAND;
|
||||
return table != null && table.contains(packageName);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -29,7 +29,7 @@ import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiJavaReference;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.psi.impl.source.tree.SourceUtil;
|
||||
import com.intellij.psi.impl.source.tree.AstBufferUtil;
|
||||
import com.intellij.util.NullableFunction;
|
||||
import com.intellij.util.PairProcessor;
|
||||
import com.intellij.util.WalkingState;
|
||||
@@ -60,8 +60,8 @@ public class SliceLeafAnalyzer {
|
||||
elementToCompare = resolved;
|
||||
}
|
||||
}
|
||||
return elementToCompare instanceof PsiNamedElement ?
|
||||
((PsiNamedElement)elementToCompare).getName() : SourceUtil.getTextSkipWhiteSpaceAndComments(elementToCompare.getNode());
|
||||
return elementToCompare instanceof PsiNamedElement ? ((PsiNamedElement)elementToCompare).getName()
|
||||
: AstBufferUtil.getTextSkippingWhitespaceComments(elementToCompare.getNode());
|
||||
}
|
||||
});
|
||||
return Comparing.hashcode(text);
|
||||
|
||||
@@ -293,9 +293,13 @@ public class AnnotationUtil {
|
||||
}
|
||||
|
||||
public static boolean isAnnotatingApplicable(@NotNull PsiElement elt) {
|
||||
return isAnnotatingApplicable(elt, NullableNotNullManager.getInstance(elt.getProject()).getDefaultNullable());
|
||||
}
|
||||
|
||||
public static boolean isAnnotatingApplicable(@NotNull PsiElement elt, final String annotationFQN) {
|
||||
final Project project = elt.getProject();
|
||||
return PsiUtil.isLanguageLevel5OrHigher(elt) &&
|
||||
JavaPsiFacade.getInstance(project).findClass(NullableNotNullManager.getInstance(project).getDefaultNullable(), elt.getResolveScope()) != null;
|
||||
JavaPsiFacade.getInstance(project).findClass(annotationFQN, elt.getResolveScope()) != null;
|
||||
}
|
||||
|
||||
public static boolean isJetbrainsAnnotation(@NonNls final String simpleName) {
|
||||
|
||||
@@ -29,9 +29,18 @@ import java.util.List;
|
||||
public abstract class HierarchicalMethodSignature extends MethodSignatureBackedByPsiMethod {
|
||||
public HierarchicalMethodSignature(@NotNull MethodSignatureBackedByPsiMethod signature) {
|
||||
super(signature.getMethod(), signature.getSubstitutor(), signature.isRaw(),
|
||||
signature.getParameterTypes(), signature.getTypeParameters());
|
||||
getParameterTypes(signature.getMethod()), signature.getTypeParameters());
|
||||
}
|
||||
|
||||
private static PsiType[] getParameterTypes(PsiMethod method) {
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
final PsiType[] paramTypes = new PsiType[parameters.length];
|
||||
for (int i = 0; i < paramTypes.length; i++) {
|
||||
paramTypes[i] = parameters[i].getType();
|
||||
}
|
||||
return paramTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of super method signatures for the specified signature.
|
||||
*
|
||||
|
||||
@@ -32,7 +32,12 @@ public class LambdaHighlightingUtil {
|
||||
final List<MethodSignature> signatures = LambdaUtil.findFunctionCandidates(psiClass);
|
||||
if (signatures == null) return "Target type of a lambda conversion must be an interface";
|
||||
if (signatures.isEmpty()) return "No target method found";
|
||||
return signatures.size() == 1 ? null : "Multiple non-overriding abstract methods found";
|
||||
if (signatures.size() == 1) {
|
||||
final MethodSignature functionalMethod = signatures.get(0);
|
||||
if (functionalMethod.getTypeParameters().length > 0) return "Target method is generic";
|
||||
return null;
|
||||
}
|
||||
return "Multiple non-overriding abstract methods found";
|
||||
}
|
||||
|
||||
public static String checkReturnTypeCompatible(PsiLambdaExpression lambdaExpression, PsiType functionalInterfaceReturnType) {
|
||||
|
||||
@@ -636,22 +636,39 @@ public class LambdaUtil {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void checkMoreSpecificReturnType(List<CandidateInfo> conflicts, int functionalInterfaceIdx) {
|
||||
public static void checkMoreSpecificReturnType(List<CandidateInfo> conflicts, PsiType[] actualParameterTypes) {
|
||||
final CandidateInfo[] newConflictsArray = conflicts.toArray(new CandidateInfo[conflicts.size()]);
|
||||
for (int i = 1; i < newConflictsArray.length; i++) {
|
||||
final CandidateInfo method = newConflictsArray[i];
|
||||
final PsiType interfaceReturnType = getReturnType(functionalInterfaceIdx, method);
|
||||
for (int j = 0; j < i; j++) {
|
||||
final CandidateInfo conflict = newConflictsArray[j];
|
||||
assert conflict != method;
|
||||
final PsiType interfaceReturnType1 = getReturnType(functionalInterfaceIdx, conflict);
|
||||
if (interfaceReturnType != null && interfaceReturnType1 != null && !Comparing.equal(interfaceReturnType, interfaceReturnType1)) {
|
||||
int moreSpecific = isMoreSpecific(interfaceReturnType, interfaceReturnType1);
|
||||
if (moreSpecific > 0) {
|
||||
int moreSpecific = 0;
|
||||
final PsiMethod methodElement = (PsiMethod)method.getElement();
|
||||
final PsiMethod conflictElement = (PsiMethod)conflict.getElement();
|
||||
if (methodElement.isVarArgs() == conflictElement.isVarArgs()) {
|
||||
for (int functionalInterfaceIdx = 0; functionalInterfaceIdx < actualParameterTypes.length; functionalInterfaceIdx++) {
|
||||
final PsiType interfaceReturnType = getReturnType(functionalInterfaceIdx, method);
|
||||
final PsiType interfaceReturnType1 = getReturnType(functionalInterfaceIdx, conflict);
|
||||
if (actualParameterTypes[functionalInterfaceIdx] instanceof PsiLambdaExpressionType || actualParameterTypes[functionalInterfaceIdx] instanceof PsiMethodReferenceType) {
|
||||
if (interfaceReturnType != null && interfaceReturnType1 != null && !Comparing.equal(interfaceReturnType, interfaceReturnType1)) {
|
||||
int moreSpecific1 = isMoreSpecific(interfaceReturnType, interfaceReturnType1, actualParameterTypes[functionalInterfaceIdx]);
|
||||
if (moreSpecific < 0 && moreSpecific1 > 0 || moreSpecific > 0 && moreSpecific1 < 0) {
|
||||
moreSpecific = 0;
|
||||
break;
|
||||
}
|
||||
moreSpecific = moreSpecific1;
|
||||
}
|
||||
} else if (interfaceReturnType != null && interfaceReturnType1 != null) {
|
||||
moreSpecific = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (moreSpecific > 0 && conflictElement.getParameterList().getParametersCount() <= actualParameterTypes.length) {
|
||||
conflicts.remove(method);
|
||||
break;
|
||||
}
|
||||
else if (moreSpecific < 0) {
|
||||
else if (moreSpecific < 0 && methodElement.getParameterList().getParametersCount() <= actualParameterTypes.length) {
|
||||
conflicts.remove(conflict);
|
||||
}
|
||||
}
|
||||
@@ -659,22 +676,38 @@ public class LambdaUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static int isMoreSpecific(PsiType returnType, PsiType returnType1) {
|
||||
enum TypeKind {
|
||||
PRIMITIVE, REFERENCE, NONE_DETERMINED
|
||||
}
|
||||
|
||||
private static int isMoreSpecific(PsiType returnType, PsiType returnType1, PsiType lambdaType) {
|
||||
if (returnType == PsiType.VOID || returnType1 == PsiType.VOID) return 0;
|
||||
if (returnType instanceof PsiPrimitiveType) {
|
||||
if (!(returnType1 instanceof PsiPrimitiveType)) {
|
||||
return -1;
|
||||
} else {
|
||||
return TypeConversionUtil.areTypesConvertible(returnType, returnType1) ? 1 : -1;
|
||||
TypeKind typeKind = TypeKind.PRIMITIVE;
|
||||
if (lambdaType instanceof PsiLambdaExpressionType) {
|
||||
typeKind = areLambdaReturnExpressionsPrimitive((PsiLambdaExpressionType)lambdaType);
|
||||
} else if (lambdaType instanceof PsiMethodReferenceType) {
|
||||
final PsiElement referencedElement = ((PsiMethodReferenceType)lambdaType).getExpression().resolve();
|
||||
if (referencedElement instanceof PsiMethod && !(((PsiMethod)referencedElement).getReturnType() instanceof PsiPrimitiveType)) {
|
||||
typeKind = TypeKind.REFERENCE;
|
||||
}
|
||||
}
|
||||
if (returnType1 instanceof PsiPrimitiveType) {
|
||||
return 1;
|
||||
if (typeKind != TypeKind.NONE_DETERMINED) {
|
||||
if (returnType instanceof PsiPrimitiveType) {
|
||||
final int moreSpecific = typeKind == TypeKind.PRIMITIVE ? 1 : -1;
|
||||
if (!(returnType1 instanceof PsiPrimitiveType)) {
|
||||
return -moreSpecific;
|
||||
} else {
|
||||
return TypeConversionUtil.isAssignable(returnType, returnType1) ? moreSpecific : -moreSpecific;
|
||||
}
|
||||
}
|
||||
if (returnType1 instanceof PsiPrimitiveType) {
|
||||
return typeKind == TypeKind.PRIMITIVE ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
final PsiClassType.ClassResolveResult r = PsiUtil.resolveGenericsClassInType(returnType);
|
||||
final PsiClassType.ClassResolveResult r = PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(returnType));
|
||||
final PsiClass rClass = r.getElement();
|
||||
final PsiClassType.ClassResolveResult r1 = PsiUtil.resolveGenericsClassInType(returnType1);
|
||||
final PsiClassType.ClassResolveResult r1 = PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(returnType1));
|
||||
final PsiClass rClass1 = r1.getElement();
|
||||
if (rClass != null && rClass1 != null) {
|
||||
if (rClass == rClass1) {
|
||||
@@ -711,6 +744,28 @@ public class LambdaUtil {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static TypeKind areLambdaReturnExpressionsPrimitive(PsiLambdaExpressionType lambdaType) {
|
||||
final List<PsiExpression> returnExpressions = getReturnExpressions(lambdaType.getExpression());
|
||||
TypeKind typeKind = TypeKind.NONE_DETERMINED;
|
||||
for (PsiExpression expression : returnExpressions) {
|
||||
final PsiType returnExprType = expression.getType();
|
||||
if (returnExprType instanceof PsiPrimitiveType) {
|
||||
if (typeKind == TypeKind.REFERENCE) {
|
||||
typeKind = TypeKind.NONE_DETERMINED;
|
||||
break;
|
||||
}
|
||||
typeKind = TypeKind.PRIMITIVE;
|
||||
} else {
|
||||
if (typeKind == TypeKind.PRIMITIVE) {
|
||||
typeKind = TypeKind.NONE_DETERMINED;
|
||||
break;
|
||||
}
|
||||
typeKind = TypeKind.REFERENCE;
|
||||
}
|
||||
}
|
||||
return typeKind;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiType getReturnType(int functionalTypeIdx, CandidateInfo method) {
|
||||
final PsiParameter[] methodParameters = ((PsiMethod)method.getElement()).getParameterList().getParameters();
|
||||
@@ -750,7 +805,7 @@ public class LambdaUtil {
|
||||
|
||||
public TypeParamsChecker(PsiElement expression, PsiClass aClass) {
|
||||
myClass = aClass;
|
||||
PsiElement parent = expression.getParent();
|
||||
PsiElement parent = expression != null ? expression.getParent() : null;
|
||||
while (parent instanceof PsiParenthesizedExpression) {
|
||||
parent = parent.getParent();
|
||||
}
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
package com.intellij.psi;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.util.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -77,12 +76,7 @@ public class PsiMethodReferenceUtil {
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
|
||||
final PsiExpression expression = methodReferenceExpression.getQualifierExpression();
|
||||
if (expression != null) {
|
||||
final PsiType expressionType = expression.getType();
|
||||
if (expressionType instanceof PsiArrayType) {
|
||||
containingClass = JavaPsiFacade.getInstance(methodReferenceExpression.getProject())
|
||||
.findClass(CommonClassNames.JAVA_LANG_OBJECT, methodReferenceExpression.getResolveScope());
|
||||
return new QualifierResolveResult(containingClass, substitutor, false);
|
||||
}
|
||||
final PsiType expressionType = getExpandedType(expression.getType(), expression);
|
||||
PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(expressionType);
|
||||
containingClass = result.getElement();
|
||||
if (containingClass != null) {
|
||||
@@ -101,7 +95,8 @@ public class PsiMethodReferenceUtil {
|
||||
else {
|
||||
final PsiTypeElement typeElement = methodReferenceExpression.getQualifierType();
|
||||
if (typeElement != null) {
|
||||
PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(typeElement.getType());
|
||||
PsiType type = getExpandedType(typeElement.getType(), typeElement);
|
||||
PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(type);
|
||||
containingClass = result.getElement();
|
||||
if (containingClass != null) {
|
||||
substitutor = result.getSubstitutor();
|
||||
@@ -149,7 +144,14 @@ public class PsiMethodReferenceUtil {
|
||||
final MethodSignature signature2 = ((PsiMethod)resolve).getSignature(subst);
|
||||
|
||||
final PsiType interfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(left);
|
||||
PsiType methodReturnType = subst.substitute(((PsiMethod)resolve).getReturnType());
|
||||
|
||||
PsiType returnType = PsiTypesUtil.patchMethodGetClassReturnType(methodReferenceExpression, methodReferenceExpression,
|
||||
(PsiMethod)resolve, null,
|
||||
PsiUtil.getLanguageLevel(methodReferenceExpression));
|
||||
if (returnType == null) {
|
||||
returnType = ((PsiMethod)resolve).getReturnType();
|
||||
}
|
||||
PsiType methodReturnType = subst.substitute(returnType);
|
||||
if (interfaceReturnType != null && interfaceReturnType != PsiType.VOID) {
|
||||
if (methodReturnType == null) {
|
||||
methodReturnType = JavaPsiFacade.getElementFactory(methodReferenceExpression.getProject()).createType(((PsiMethod)resolve).getContainingClass(), subst);
|
||||
@@ -161,9 +163,18 @@ public class PsiMethodReferenceUtil {
|
||||
final PsiType interfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(left);
|
||||
if (interfaceReturnType != null) {
|
||||
if (interfaceReturnType == PsiType.VOID) return true;
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
if (resolve == JavaPsiFacade.getElementFactory(resolve.getProject()).getArrayClass(PsiUtil.getLanguageLevel(resolve))) {
|
||||
if (parameters.length != 1 || parameters[0].getType() != PsiType.INT) return false;
|
||||
final PsiTypeParameter[] typeParameters = ((PsiClass)resolve).getTypeParameters();
|
||||
if (typeParameters.length == 1) {
|
||||
final PsiType arrayComponentType = result.getSubstitutor().substitute(typeParameters[0]);
|
||||
return arrayComponentType != null && TypeConversionUtil.isAssignable(interfaceReturnType, arrayComponentType.createArrayType(), true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final PsiClassType classType = JavaPsiFacade.getElementFactory(methodReferenceExpression.getProject()).createType((PsiClass)resolve, result.getSubstitutor());
|
||||
if (TypeConversionUtil.isAssignable(interfaceReturnType, classType, !((PsiClass)resolve).hasTypeParameters())) {
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
if (parameters.length == 0) return true;
|
||||
if (parameters.length == 1) {
|
||||
if (isReceiverType(resolveResult.getSubstitutor().substitute(parameters[0].getType()), qualifierResolveResult.getContainingClass(), qualifierResolveResult.getSubstitutor())) return true;
|
||||
@@ -176,14 +187,13 @@ public class PsiMethodReferenceUtil {
|
||||
}
|
||||
|
||||
private static boolean isReceiverType(@Nullable PsiClass aClass, @Nullable PsiClass containingClass) {
|
||||
while (containingClass != null) {
|
||||
if (InheritanceUtil.isInheritorOrSelf(aClass, containingClass, true)) return true;
|
||||
containingClass = containingClass.getContainingClass();
|
||||
}
|
||||
return false;
|
||||
return InheritanceUtil.isInheritorOrSelf(aClass, containingClass, true);
|
||||
}
|
||||
|
||||
public static boolean isReceiverType(PsiType receiverType, @Nullable PsiClass containingClass, PsiSubstitutor psiSubstitutor) {
|
||||
if (containingClass != null) {
|
||||
receiverType = getExpandedType(receiverType, containingClass);
|
||||
}
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(receiverType));
|
||||
final PsiClass receiverClass = resolveResult.getElement();
|
||||
if (receiverClass != null && isReceiverType(receiverClass, containingClass)) {
|
||||
@@ -264,14 +274,23 @@ public class PsiMethodReferenceUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static PsiLocalVariable createMethodReferenceExpressionAccording2Type(PsiMethodReferenceExpression methodReferenceExpression,
|
||||
PsiType leftType) {
|
||||
final String uniqueVarName =
|
||||
JavaCodeStyleManager.getInstance(methodReferenceExpression.getProject())
|
||||
.suggestUniqueVariableName("l", methodReferenceExpression, true);
|
||||
final PsiStatement assignmentFromText = JavaPsiFacade.getElementFactory(methodReferenceExpression.getProject())
|
||||
.createStatementFromText(leftType.getCanonicalText() + " " + uniqueVarName + " = " + methodReferenceExpression.getText(),
|
||||
methodReferenceExpression);
|
||||
return (PsiLocalVariable)((PsiDeclarationStatement)assignmentFromText).getDeclaredElements()[0];
|
||||
|
||||
public static boolean onArrayType(PsiClass containingClass, MethodSignature signature) {
|
||||
if (signature.getParameterTypes().length == 1 && signature.getParameterTypes()[0] == PsiType.INT) {
|
||||
if (containingClass != null) {
|
||||
final Project project = containingClass.getProject();
|
||||
final LanguageLevel level = PsiUtil.getLanguageLevel(containingClass);
|
||||
return containingClass == JavaPsiFacade.getElementFactory(project).getArrayClass(level);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static PsiType getExpandedType(PsiType type, @NotNull PsiElement typeElement) {
|
||||
if (type instanceof PsiArrayType) {
|
||||
type = JavaPsiFacade.getElementFactory(typeElement.getProject()).getArrayClassType(((PsiArrayType)type).getComponentType(),
|
||||
PsiUtil.getLanguageLevel(typeElement));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -67,17 +67,12 @@ public abstract class PsiNameHelper {
|
||||
|
||||
@NotNull
|
||||
public static String getShortClassName(@NotNull String referenceText) {
|
||||
return getShortClassName(referenceText, true);
|
||||
}
|
||||
int lessPos = referenceText.length(), bracesBalance = 0, i;
|
||||
|
||||
private static String getShortClassName(String referenceText, boolean removeWhitespace) {
|
||||
int lessPos = referenceText.length();
|
||||
int bracesBalance = 0;
|
||||
int i;
|
||||
loop:
|
||||
for (i = referenceText.length() - 1; i >= 0; i--) {
|
||||
final char aChar = referenceText.charAt(i);
|
||||
switch (aChar) {
|
||||
char ch = referenceText.charAt(i);
|
||||
switch (ch) {
|
||||
case ')':
|
||||
case '>':
|
||||
bracesBalance++;
|
||||
@@ -91,22 +86,25 @@ public abstract class PsiNameHelper {
|
||||
|
||||
case '@':
|
||||
case '.':
|
||||
if (bracesBalance == 0) break loop;
|
||||
if (bracesBalance <= 0) break loop;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (bracesBalance == 0 && removeWhitespace && !Character.isWhitespace(aChar) && !Character.isJavaIdentifierPart(aChar)) {
|
||||
return getShortClassName(removeWhitespace(referenceText), false);
|
||||
if (Character.isWhitespace(ch) && bracesBalance <= 0) {
|
||||
for (int j = i + 1; j < lessPos; j++) {
|
||||
if (!Character.isWhitespace(referenceText.charAt(j))) break loop;
|
||||
}
|
||||
lessPos = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String sub = referenceText.substring(i + 1, lessPos).trim();
|
||||
return sub.length() == referenceText.length() ? sub : new String(sub);
|
||||
}
|
||||
|
||||
public static String getPresentableText(PsiJavaCodeReferenceElement ref) {
|
||||
final String referenceName = ref.getReferenceName();
|
||||
|
||||
PsiType[] typeParameters = ref.getTypeParameters();
|
||||
return getPresentableText(referenceName, typeParameters);
|
||||
}
|
||||
@@ -167,7 +165,7 @@ public abstract class PsiNameHelper {
|
||||
* <code>["List<String>","Integer"]</code>
|
||||
*
|
||||
* @param referenceText the text of the reference to calculate type parameters for.
|
||||
* @return the calculated array of type parameters.
|
||||
* @return the calculated array of type parameters.
|
||||
*/
|
||||
public static String[] getClassParametersText(String referenceText) {
|
||||
if (referenceText.indexOf('<') < 0) return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
|
||||
@@ -15,7 +15,13 @@
|
||||
*/
|
||||
package com.intellij.psi.util;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -47,6 +53,8 @@ public class PsiTypesUtil {
|
||||
ourBoxedTypes.put("char", CommonClassNames.JAVA_LANG_CHARACTER);
|
||||
}
|
||||
|
||||
@NonNls private static final String GET_CLASS_METHOD = "getClass";
|
||||
|
||||
private PsiTypesUtil() { }
|
||||
|
||||
public static String getDefaultValueOfType(PsiType type) {
|
||||
@@ -135,4 +143,45 @@ public class PsiTypesUtil {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PsiType patchMethodGetClassReturnType(@NotNull PsiExpression call,
|
||||
@NotNull PsiReferenceExpression methodExpression,
|
||||
@NotNull PsiMethod method,
|
||||
@Nullable Condition<IElementType> condition,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
//JLS3 15.8.2
|
||||
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_5) &&
|
||||
GET_CLASS_METHOD.equals(method.getName()) &&
|
||||
CommonClassNames.JAVA_LANG_OBJECT.equals(method.getContainingClass().getQualifiedName())) {
|
||||
PsiExpression qualifier = methodExpression.getQualifierExpression();
|
||||
PsiType qualifierType = null;
|
||||
final Project project = call.getProject();
|
||||
if (qualifier != null) {
|
||||
qualifierType = TypeConversionUtil.erasure(qualifier.getType());
|
||||
}
|
||||
else if (condition != null) {
|
||||
ASTNode parent = call.getNode().getTreeParent();
|
||||
while (parent != null && condition.value(parent.getElementType())) {
|
||||
parent = parent.getTreeParent();
|
||||
}
|
||||
if (parent != null) {
|
||||
qualifierType = JavaPsiFacade.getInstance(project).getElementFactory().createType((PsiClass)parent.getPsi());
|
||||
}
|
||||
}
|
||||
if (qualifierType != null) {
|
||||
PsiClass javaLangClass = JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_LANG_CLASS, call.getResolveScope());
|
||||
if (javaLangClass != null && javaLangClass.getTypeParameters().length == 1) {
|
||||
Map<PsiTypeParameter, PsiType> map = new HashMap<PsiTypeParameter, PsiType>();
|
||||
map.put(javaLangClass.getTypeParameters()[0], PsiWildcardType.createExtends(call.getManager(), qualifierType));
|
||||
PsiSubstitutor substitutor = JavaPsiFacade.getInstance(project).getElementFactory().createSubstitutor(map);
|
||||
final PsiClassType classType = JavaPsiFacade.getInstance(project).getElementFactory()
|
||||
.createType(javaLangClass, substitutor, languageLevel);
|
||||
final PsiElement parent = call.getParent();
|
||||
return parent instanceof PsiReferenceExpression && parent.getParent() instanceof PsiMethodCallExpression
|
||||
? PsiUtil.captureToplevelWildcards(classType, methodExpression) : classType;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -32,6 +32,7 @@ import com.intellij.psi.meta.PsiMetaData;
|
||||
import com.intellij.psi.meta.PsiMetaOwner;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.EmptyIterable;
|
||||
@@ -473,7 +474,7 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
PsiType argType = args[args.length - 1];
|
||||
if (argType == null) return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
if (TypeConversionUtil.isAssignable(parmType, argType)) return ApplicabilityLevel.FIXED_ARITY;
|
||||
|
||||
|
||||
if (isRaw) {
|
||||
final PsiType erasedParamType = TypeConversionUtil.erasure(parmType);
|
||||
final PsiType erasedArgType = TypeConversionUtil.erasure(argType);
|
||||
@@ -550,7 +551,7 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
if (typeParameters1.length != typeParameters2.length) return false;
|
||||
for (int i = 0; i < typeParameters1.length; i++) {
|
||||
final PsiType substituted2 = s2.substitute(typeParameters2[i]);
|
||||
if (!Comparing.equal(s1.substituteWithBoundsPromotion(typeParameters1[i]), substituted2) &&
|
||||
if (!Comparing.equal(s1.substituteWithBoundsPromotion(typeParameters1[i]), substituted2) &&
|
||||
!Comparing.equal(s1.substitute(typeParameters1[i]), substituted2)) return false;
|
||||
}
|
||||
if (aClass.hasModifierProperty(PsiModifier.STATIC)) return true;
|
||||
@@ -858,7 +859,7 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
public static boolean hasDefaultConstructor(@NotNull PsiClass clazz) {
|
||||
return hasDefaultConstructor(clazz, false);
|
||||
}
|
||||
|
||||
|
||||
public static boolean hasDefaultConstructor(@NotNull PsiClass clazz, boolean allowProtected) {
|
||||
return hasDefaultConstructor(clazz, allowProtected, true);
|
||||
}
|
||||
@@ -949,10 +950,14 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
return parent instanceof PsiIfStatement && element == ((PsiIfStatement)parent).getElseBranch();
|
||||
}
|
||||
|
||||
public static boolean isJavaToken(@Nullable final PsiElement element, final IElementType type) {
|
||||
public static boolean isJavaToken(@Nullable PsiElement element, IElementType type) {
|
||||
return element instanceof PsiJavaToken && ((PsiJavaToken)element).getTokenType() == type;
|
||||
}
|
||||
|
||||
public static boolean isJavaToken(@Nullable PsiElement element, @NotNull TokenSet types) {
|
||||
return element instanceof PsiJavaToken && types.contains(((PsiJavaToken)element).getTokenType());
|
||||
}
|
||||
|
||||
public static boolean isCatchParameter(@Nullable final PsiElement element) {
|
||||
return element instanceof PsiParameter && element.getParent() instanceof PsiCatchSection;
|
||||
}
|
||||
|
||||
@@ -686,6 +686,9 @@ public class TypeConversionUtil {
|
||||
final PsiType lType = lLambdaExpression.getFunctionalInterfaceType();
|
||||
return Comparing.equal(rType, lType);
|
||||
}
|
||||
if (left instanceof PsiArrayType) {
|
||||
return false;
|
||||
}
|
||||
return LambdaUtil.isAcceptable(rLambdaExpression, left, false);
|
||||
}
|
||||
|
||||
@@ -815,21 +818,6 @@ public class TypeConversionUtil {
|
||||
}
|
||||
|
||||
public static boolean boxingConversionApplicable(final PsiType left, final PsiType right) {
|
||||
if (right instanceof PsiMethodReferenceType) {
|
||||
final JavaResolveResult result = ((PsiMethodReferenceType)right).getExpression().advancedResolve(false);
|
||||
PsiElement element = result.getElement();
|
||||
final PsiClassType.ClassResolveResult functionalInterfaceResult = PsiUtil.resolveGenericsClassInType(left);
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceResult);
|
||||
if (element instanceof PsiMethod && interfaceMethod != null) {
|
||||
final PsiType[] parameterTypes = ((PsiMethod)element).getSignature(result.getSubstitutor()).getParameterTypes();
|
||||
final PsiType[] argTypes = interfaceMethod.getSignature(functionalInterfaceResult.getSubstitutor()).getParameterTypes();
|
||||
if (parameterTypes.length != argTypes.length) return false;
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
if (boxingConversionApplicable(parameterTypes[i], argTypes[i])) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (left instanceof PsiPrimitiveType && !PsiType.NULL.equals(left)) {
|
||||
return right instanceof PsiClassType && isAssignable(left, right);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -402,29 +402,26 @@ public class DeclarationParser {
|
||||
return Pair.create(modList, isEmpty);
|
||||
}
|
||||
|
||||
private PsiBuilder.Marker parseMethodFromLeftParenth(final PsiBuilder builder, final PsiBuilder.Marker declaration,
|
||||
final boolean anno, final boolean constructor) {
|
||||
private PsiBuilder.Marker parseMethodFromLeftParenth(PsiBuilder builder, PsiBuilder.Marker declaration, boolean anno, boolean constructor) {
|
||||
parseParameterList(builder);
|
||||
|
||||
eatBrackets(builder, constructor, "expected.semicolon");
|
||||
|
||||
myParser.getReferenceParser().parseReferenceList(builder, JavaTokenType.THROWS_KEYWORD, JavaElementType.THROWS_LIST, JavaTokenType.COMMA);
|
||||
|
||||
final boolean hasDefault = expect(builder, JavaTokenType.DEFAULT_KEYWORD);
|
||||
if (hasDefault && anno) {
|
||||
if (anno && expect(builder, JavaTokenType.DEFAULT_KEYWORD)) {
|
||||
parseAnnotationValue(builder);
|
||||
}
|
||||
|
||||
final IElementType tokenType = builder.getTokenType();
|
||||
final boolean hasError = tokenType != JavaTokenType.SEMICOLON && tokenType != JavaTokenType.LBRACE;
|
||||
if (hasError) {
|
||||
final PsiBuilder.Marker error = builder.mark();
|
||||
IElementType tokenType = builder.getTokenType();
|
||||
if (tokenType != JavaTokenType.SEMICOLON && tokenType != JavaTokenType.LBRACE) {
|
||||
PsiBuilder.Marker error = builder.mark();
|
||||
// heuristic: going to next line obviously means method signature is over, starting new method (actually, another one completion hack)
|
||||
final CharSequence text = builder.getOriginalText();
|
||||
CharSequence text = builder.getOriginalText();
|
||||
Loop:
|
||||
while (true) {
|
||||
for (int i = builder.getCurrentOffset() - 1; i >= 0; i--) {
|
||||
final char ch = text.charAt(i);
|
||||
char ch = text.charAt(i);
|
||||
if (ch == '\n') break Loop;
|
||||
else if (ch != ' ' && ch != '\t') break;
|
||||
}
|
||||
@@ -433,11 +430,10 @@ public class DeclarationParser {
|
||||
error.error(JavaErrorMessages.message("expected.lbrace.or.semicolon"));
|
||||
}
|
||||
|
||||
if (hasDefault && !anno && !hasError && builder.getTokenType() != JavaTokenType.LBRACE) {
|
||||
error(builder, JavaErrorMessages.message("expected.lbrace"));
|
||||
}
|
||||
if (!expect(builder, JavaTokenType.SEMICOLON) && builder.getTokenType() == JavaTokenType.LBRACE) {
|
||||
myParser.getStatementParser().parseCodeBlock(builder);
|
||||
if (!expect(builder, JavaTokenType.SEMICOLON)) {
|
||||
if (builder.getTokenType() == JavaTokenType.LBRACE) {
|
||||
myParser.getStatementParser().parseCodeBlock(builder);
|
||||
}
|
||||
}
|
||||
|
||||
done(declaration, anno ? JavaElementType.ANNOTATION_METHOD : JavaElementType.METHOD);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.psi.impl;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -25,6 +26,7 @@ import java.util.Map;
|
||||
* @author dsl
|
||||
*/
|
||||
public final class EmptySubstitutorImpl extends EmptySubstitutor {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.EmptySubstitutorImpl");
|
||||
@Override
|
||||
public PsiType substitute(@NotNull PsiTypeParameter typeParameter){
|
||||
return JavaPsiFacade.getInstance(typeParameter.getProject()).getElementFactory().createType(typeParameter);
|
||||
@@ -42,6 +44,9 @@ public final class EmptySubstitutorImpl extends EmptySubstitutor {
|
||||
|
||||
@Override
|
||||
public PsiSubstitutor put(PsiTypeParameter classParameter, PsiType mapping){
|
||||
if (mapping != null && !mapping.isValid()) {
|
||||
LOG.error("Invalid type in substitutor: " + mapping);
|
||||
}
|
||||
return new PsiSubstitutorImpl(classParameter, mapping);
|
||||
}
|
||||
|
||||
|
||||
@@ -414,6 +414,9 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
|
||||
@Override
|
||||
public PsiSubstitutor put(@NotNull PsiTypeParameter typeParameter, PsiType mapping) {
|
||||
PsiSubstitutorImpl ret = clone();
|
||||
if (mapping != null && !mapping.isValid()) {
|
||||
LOG.error("Invalid type in substitutor: " + mapping);
|
||||
}
|
||||
ret.mySubstitutionMap.put(typeParameter, mapping);
|
||||
return ret;
|
||||
}
|
||||
@@ -425,7 +428,11 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
|
||||
PsiTypeParameter param = params[i];
|
||||
assert param != null;
|
||||
if (mappings != null && mappings.length > i) {
|
||||
mySubstitutionMap.put(param, mappings[i]);
|
||||
PsiType mapping = mappings[i];
|
||||
mySubstitutionMap.put(param, mapping);
|
||||
if (mapping != null && !mapping.isValid()) {
|
||||
LOG.error("Invalid type in substitutor: " + mapping);
|
||||
}
|
||||
}
|
||||
else {
|
||||
mySubstitutionMap.put(param, null);
|
||||
|
||||
@@ -18,9 +18,10 @@ package com.intellij.psi.impl.cache;
|
||||
import com.intellij.lang.LighterAST;
|
||||
import com.intellij.lang.LighterASTNode;
|
||||
import com.intellij.lang.LighterASTTokenNode;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiModifierList;
|
||||
import com.intellij.psi.impl.java.stubs.*;
|
||||
import com.intellij.psi.impl.java.stubs.impl.PsiMethodStubImpl;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.impl.source.tree.LightTreeUtil;
|
||||
import com.intellij.psi.stubs.PsiFileStub;
|
||||
@@ -59,8 +60,8 @@ public class RecordUtil {
|
||||
|
||||
public static boolean isDeprecatedByDocComment(@NotNull LighterAST tree, @NotNull LighterASTNode comment) {
|
||||
// todo[r.sh] parse doc comments, implement tree lookup
|
||||
final String text = LightTreeUtil.toFilteredString(tree, comment, null);
|
||||
return text != null && text.contains(DEPRECATED_TAG);
|
||||
String text = LightTreeUtil.toFilteredString(tree, comment, null);
|
||||
return text.contains(DEPRECATED_TAG);
|
||||
}
|
||||
|
||||
public static int packModifierList(@NotNull LighterAST tree, @NotNull LighterASTNode modList, @NotNull StubElement parent) {
|
||||
@@ -110,12 +111,7 @@ public class RecordUtil {
|
||||
else if (parent instanceof PsiMethodStub) {
|
||||
if (grandParent instanceof PsiClassStub && ((PsiClassStub)grandParent).isInterface()) {
|
||||
packed |= ModifierFlags.PUBLIC_MASK;
|
||||
if (parent instanceof PsiMethodStubImpl && ((PsiMethodStubImpl)parent).hasExtensionMethodMark()) {
|
||||
packed |= ModifierFlags.DEFENDER_MASK;
|
||||
}
|
||||
else {
|
||||
packed |= ModifierFlags.ABSTRACT_MASK;
|
||||
}
|
||||
packed |= ModifierFlags.ABSTRACT_MASK;
|
||||
}
|
||||
}
|
||||
else if (parent instanceof PsiFieldStub) {
|
||||
|
||||
@@ -91,20 +91,42 @@ public class TypeInfo {
|
||||
public final boolean isEllipsis;
|
||||
private final List<PsiAnnotationStub> myAnnotationStubs;
|
||||
|
||||
public TypeInfo(StringRef text, byte arrayCount, boolean ellipsis, @NotNull List<PsiAnnotationStub> annotationStubs) {
|
||||
this.text = text;
|
||||
this.arrayCount = arrayCount;
|
||||
public TypeInfo(StringRef _text, byte _arrayCount, boolean ellipsis, @NotNull List<PsiAnnotationStub> annotationStubs) {
|
||||
text = _text;
|
||||
arrayCount = _arrayCount;
|
||||
isEllipsis = ellipsis;
|
||||
myAnnotationStubs = annotationStubs;
|
||||
}
|
||||
|
||||
public TypeInfo(@NotNull TypeInfo typeInfo) {
|
||||
this.text = typeInfo.text;
|
||||
this.arrayCount = typeInfo.arrayCount;
|
||||
text = typeInfo.text;
|
||||
arrayCount = typeInfo.arrayCount;
|
||||
isEllipsis = typeInfo.isEllipsis;
|
||||
myAnnotationStubs = new SmartList<PsiAnnotationStub>(typeInfo.myAnnotationStubs);
|
||||
}
|
||||
|
||||
public void addAnnotation(PsiAnnotationStub annotation) {
|
||||
myAnnotationStubs.add(annotation);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getShortTypeText() {
|
||||
if (text == null) return "";
|
||||
String name = PsiNameHelper.getShortClassName(text.getString());
|
||||
if (arrayCount > 0) {
|
||||
name += StringUtil.repeat("[]", arrayCount);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String text = createTypeText(this);
|
||||
return text != null ? text : "null";
|
||||
}
|
||||
|
||||
/* factories and serialization */
|
||||
|
||||
@NotNull
|
||||
public static TypeInfo createConstructorType() {
|
||||
return NULL;
|
||||
@@ -162,7 +184,7 @@ public class TypeInfo {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TypeInfo fromString(String typeText, boolean isEllipsis) {
|
||||
public static TypeInfo fromString(@NotNull String typeText, boolean isEllipsis) {
|
||||
assert !typeText.endsWith("...") : typeText;
|
||||
|
||||
byte arrayCount = 0;
|
||||
@@ -277,15 +299,4 @@ public class TypeInfo {
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public void addAnnotation(PsiAnnotationStub annotation) {
|
||||
myAnnotationStubs.add(annotation);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getShortTypeText() {
|
||||
if (text == null) return "";
|
||||
String name = PsiNameHelper.getShortClassName(text.getString());
|
||||
return arrayCount > 0 ? name + StringUtil.repeat("[]", arrayCount) : name;
|
||||
}
|
||||
}
|
||||
|
||||
+65
-70
@@ -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.
|
||||
@@ -18,6 +18,7 @@ package com.intellij.psi.impl.java.stubs;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.LighterAST;
|
||||
import com.intellij.lang.LighterASTNode;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiNameHelper;
|
||||
import com.intellij.psi.PsiReferenceList;
|
||||
import com.intellij.psi.impl.java.stubs.impl.PsiClassReferenceListStubImpl;
|
||||
@@ -48,54 +49,29 @@ public abstract class JavaClassReferenceListElementType extends JavaStubElementT
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReferenceList createPsi(@NotNull final PsiClassReferenceListStub stub) {
|
||||
public PsiReferenceList createPsi(@NotNull PsiClassReferenceListStub stub) {
|
||||
return getPsiFactory(stub).createClassReferenceList(stub);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReferenceList createPsi(@NotNull final ASTNode node) {
|
||||
public PsiReferenceList createPsi(@NotNull ASTNode node) {
|
||||
if (node.getElementType() == JavaStubElementTypes.EXTENDS_BOUND_LIST) {
|
||||
return new PsiTypeParameterExtendsBoundsListImpl(node);
|
||||
}
|
||||
|
||||
return new PsiReferenceListImpl(node);
|
||||
else {
|
||||
return new PsiReferenceListImpl(node);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiClassReferenceListStub createStub(final LighterAST tree,
|
||||
final LighterASTNode node,
|
||||
final StubElement parentStub) {
|
||||
final JavaClassReferenceListElementType type = (JavaClassReferenceListElementType)node.getTokenType();
|
||||
public PsiClassReferenceListStub createStub(LighterAST tree, LighterASTNode node, StubElement parentStub) {
|
||||
JavaClassReferenceListElementType type = (JavaClassReferenceListElementType)node.getTokenType();
|
||||
return new PsiClassReferenceListStubImpl(type, parentStub, getTexts(tree, node), elementTypeToRole(type));
|
||||
}
|
||||
|
||||
private static JavaClassReferenceListElementType roleToElementType(final PsiReferenceList.Role role) {
|
||||
switch (role) {
|
||||
case EXTENDS_BOUNDS_LIST:
|
||||
return JavaStubElementTypes.EXTENDS_BOUND_LIST;
|
||||
case EXTENDS_LIST:
|
||||
return JavaStubElementTypes.EXTENDS_LIST;
|
||||
case IMPLEMENTS_LIST:
|
||||
return JavaStubElementTypes.IMPLEMENTS_LIST;
|
||||
case THROWS_LIST:
|
||||
return JavaStubElementTypes.THROWS_LIST;
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unknown role: " + role);
|
||||
}
|
||||
|
||||
private static PsiReferenceList.Role elementTypeToRole(final IElementType type) {
|
||||
if (type == JavaStubElementTypes.EXTENDS_BOUND_LIST) return PsiReferenceList.Role.EXTENDS_BOUNDS_LIST;
|
||||
else if (type == JavaStubElementTypes.EXTENDS_LIST) return PsiReferenceList.Role.EXTENDS_LIST;
|
||||
else if (type == JavaStubElementTypes.IMPLEMENTS_LIST) return PsiReferenceList.Role.IMPLEMENTS_LIST;
|
||||
else if (type == JavaStubElementTypes.THROWS_LIST) return PsiReferenceList.Role.THROWS_LIST;
|
||||
|
||||
throw new RuntimeException("Unknown element type: " + type);
|
||||
}
|
||||
|
||||
private static String[] getTexts(final LighterAST tree, final LighterASTNode node) {
|
||||
final List<LighterASTNode> refs = LightTreeUtil.getChildrenOfType(tree, node, JavaElementType.JAVA_CODE_REFERENCE);
|
||||
final String[] texts = ArrayUtil.newStringArray(refs.size());
|
||||
private static String[] getTexts(LighterAST tree, LighterASTNode node) {
|
||||
List<LighterASTNode> refs = LightTreeUtil.getChildrenOfType(tree, node, JavaElementType.JAVA_CODE_REFERENCE);
|
||||
String[] texts = ArrayUtil.newStringArray(refs.size());
|
||||
for (int i = 0; i < refs.size(); i++) {
|
||||
texts[i] = LightTreeUtil.toFilteredString(tree, refs.get(i), null);
|
||||
}
|
||||
@@ -103,9 +79,11 @@ public abstract class JavaClassReferenceListElementType extends JavaStubElementT
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(final PsiClassReferenceListStub stub, final StubOutputStream dataStream) throws IOException {
|
||||
dataStream.writeByte(encodeRole(stub.getRole()));
|
||||
final String[] names = stub.getReferencedNames();
|
||||
public void serialize(PsiClassReferenceListStub stub, StubOutputStream dataStream) throws IOException {
|
||||
byte role = encodeRole(stub.getRole());
|
||||
dataStream.writeByte(role);
|
||||
|
||||
String[] names = stub.getReferencedNames();
|
||||
dataStream.writeVarInt(names.length);
|
||||
for (String name : names) {
|
||||
dataStream.writeName(name);
|
||||
@@ -113,49 +91,29 @@ public abstract class JavaClassReferenceListElementType extends JavaStubElementT
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiClassReferenceListStub deserialize(final StubInputStream dataStream, final StubElement parentStub) throws IOException {
|
||||
public PsiClassReferenceListStub deserialize(StubInputStream dataStream, StubElement parentStub) throws IOException {
|
||||
byte role = dataStream.readByte();
|
||||
|
||||
int len = dataStream.readVarInt();
|
||||
StringRef[] names = StringRef.createArray(len);
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
names[i] = dataStream.readName();
|
||||
}
|
||||
|
||||
final PsiReferenceList.Role decodedRole = decodeRole(role);
|
||||
PsiReferenceList.Role decodedRole = decodeRole(role);
|
||||
return new PsiClassReferenceListStubImpl(roleToElementType(decodedRole), parentStub, names, decodedRole);
|
||||
}
|
||||
|
||||
private static PsiReferenceList.Role decodeRole(int code) {
|
||||
switch (code) {
|
||||
case 0: return PsiReferenceList.Role.EXTENDS_LIST;
|
||||
case 1: return PsiReferenceList.Role.IMPLEMENTS_LIST;
|
||||
case 2: return PsiReferenceList.Role.THROWS_LIST;
|
||||
case 3: return PsiReferenceList.Role.EXTENDS_BOUNDS_LIST;
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Unknown role code: " + code);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte encodeRole(PsiReferenceList.Role role) {
|
||||
switch (role) {
|
||||
case EXTENDS_LIST: return 0;
|
||||
case IMPLEMENTS_LIST: return 1;
|
||||
case THROWS_LIST: return 2;
|
||||
case EXTENDS_BOUNDS_LIST: return 3;
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Unknown role code: " + role);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void indexStub(final PsiClassReferenceListStub stub, final IndexSink sink) {
|
||||
final PsiReferenceList.Role role = stub.getRole();
|
||||
public void indexStub(PsiClassReferenceListStub stub, IndexSink sink) {
|
||||
PsiReferenceList.Role role = stub.getRole();
|
||||
if (role == PsiReferenceList.Role.EXTENDS_LIST || role == PsiReferenceList.Role.IMPLEMENTS_LIST) {
|
||||
final String[] names = stub.getReferencedNames();
|
||||
String[] names = stub.getReferencedNames();
|
||||
for (String name : names) {
|
||||
sink.occurrence(JavaStubIndexKeys.SUPER_CLASSES, PsiNameHelper.getShortClassName(name));
|
||||
String shortName = PsiNameHelper.getShortClassName(name);
|
||||
if (!StringUtil.isEmptyOrSpaces(shortName)) {
|
||||
sink.occurrence(JavaStubIndexKeys.SUPER_CLASSES, shortName);
|
||||
}
|
||||
}
|
||||
|
||||
if (role == PsiReferenceList.Role.EXTENDS_LIST) {
|
||||
@@ -165,7 +123,6 @@ public abstract class JavaClassReferenceListElementType extends JavaStubElementT
|
||||
if (psiClassStub.isEnum()) {
|
||||
sink.occurrence(JavaStubIndexKeys.SUPER_CLASSES, "Enum");
|
||||
}
|
||||
|
||||
if (psiClassStub.isAnnotationType()) {
|
||||
sink.occurrence(JavaStubIndexKeys.SUPER_CLASSES, "Annotation");
|
||||
}
|
||||
@@ -173,4 +130,42 @@ public abstract class JavaClassReferenceListElementType extends JavaStubElementT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiReferenceList.Role elementTypeToRole(IElementType type) {
|
||||
if (type == JavaStubElementTypes.EXTENDS_BOUND_LIST) return PsiReferenceList.Role.EXTENDS_BOUNDS_LIST;
|
||||
else if (type == JavaStubElementTypes.EXTENDS_LIST) return PsiReferenceList.Role.EXTENDS_LIST;
|
||||
else if (type == JavaStubElementTypes.IMPLEMENTS_LIST) return PsiReferenceList.Role.IMPLEMENTS_LIST;
|
||||
else if (type == JavaStubElementTypes.THROWS_LIST) return PsiReferenceList.Role.THROWS_LIST;
|
||||
throw new RuntimeException("Unknown element type: " + type);
|
||||
}
|
||||
|
||||
private static JavaClassReferenceListElementType roleToElementType(PsiReferenceList.Role role) {
|
||||
switch (role) {
|
||||
case EXTENDS_BOUNDS_LIST: return JavaStubElementTypes.EXTENDS_BOUND_LIST;
|
||||
case EXTENDS_LIST: return JavaStubElementTypes.EXTENDS_LIST;
|
||||
case IMPLEMENTS_LIST: return JavaStubElementTypes.IMPLEMENTS_LIST;
|
||||
case THROWS_LIST: return JavaStubElementTypes.THROWS_LIST;
|
||||
}
|
||||
throw new RuntimeException("Unknown role: " + role);
|
||||
}
|
||||
|
||||
private static byte encodeRole(PsiReferenceList.Role role) {
|
||||
switch (role) {
|
||||
case EXTENDS_LIST: return 0;
|
||||
case IMPLEMENTS_LIST: return 1;
|
||||
case THROWS_LIST: return 2;
|
||||
case EXTENDS_BOUNDS_LIST: return 3;
|
||||
}
|
||||
throw new RuntimeException("Unknown role: " + role);
|
||||
}
|
||||
|
||||
private static PsiReferenceList.Role decodeRole(byte code) {
|
||||
switch (code) {
|
||||
case 0: return PsiReferenceList.Role.EXTENDS_LIST;
|
||||
case 1: return PsiReferenceList.Role.IMPLEMENTS_LIST;
|
||||
case 2: return PsiReferenceList.Role.THROWS_LIST;
|
||||
case 3: return PsiReferenceList.Role.EXTENDS_BOUNDS_LIST;
|
||||
}
|
||||
throw new RuntimeException("Unknown role code: " + code);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-8
@@ -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.
|
||||
@@ -61,23 +61,21 @@ public abstract class JavaImportStatementElementType extends JavaStubElementType
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiImportStatementStub createStub(final LighterAST tree,
|
||||
final LighterASTNode node,
|
||||
final StubElement parentStub) {
|
||||
public PsiImportStatementStub createStub(LighterAST tree, LighterASTNode node, StubElement parentStub) {
|
||||
boolean isOnDemand = false;
|
||||
String refText = null;
|
||||
|
||||
for (final LighterASTNode child : tree.getChildren(node)) {
|
||||
final IElementType type = child.getTokenType();
|
||||
for (LighterASTNode child : tree.getChildren(node)) {
|
||||
IElementType type = child.getTokenType();
|
||||
if (type == JavaElementType.JAVA_CODE_REFERENCE || type == JavaElementType.IMPORT_STATIC_REFERENCE) {
|
||||
refText = SourceUtil.getTextSkipWhiteSpaceAndComments(tree, child);
|
||||
refText = SourceUtil.getReferenceText(tree, child);
|
||||
}
|
||||
else if (type == JavaTokenType.ASTERISK) {
|
||||
isOnDemand = true;
|
||||
}
|
||||
}
|
||||
|
||||
final byte flags = PsiImportStatementStubImpl.packFlags(isOnDemand, node.getTokenType() == JavaElementType.IMPORT_STATIC_STATEMENT);
|
||||
byte flags = PsiImportStatementStubImpl.packFlags(isOnDemand, node.getTokenType() == JavaElementType.IMPORT_STATIC_STATEMENT);
|
||||
return new PsiImportStatementStubImpl(parentStub, refText, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -73,7 +73,6 @@ public abstract class JavaMethodElementType extends JavaStubElementType<PsiMetho
|
||||
boolean isVarArgs = false;
|
||||
boolean isDeprecatedByComment = false;
|
||||
boolean hasDeprecatedAnnotation = false;
|
||||
boolean isExtension = false;
|
||||
String defValueText = null;
|
||||
|
||||
boolean expectingDef = false;
|
||||
@@ -103,24 +102,18 @@ public abstract class JavaMethodElementType extends JavaStubElementType<PsiMetho
|
||||
else if (type == JavaTokenType.DEFAULT_KEYWORD) {
|
||||
expectingDef = true;
|
||||
}
|
||||
else if (expectingDef && !ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET.contains(type) && type != JavaTokenType.SEMICOLON) {
|
||||
if (type != JavaElementType.CODE_BLOCK) {
|
||||
defValueText = LightTreeUtil.toFilteredString(tree, child, null);
|
||||
}
|
||||
else {
|
||||
isExtension = true;
|
||||
}
|
||||
else if (expectingDef && !ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET.contains(type) &&
|
||||
type != JavaTokenType.SEMICOLON && type != JavaElementType.CODE_BLOCK) {
|
||||
defValueText = LightTreeUtil.toFilteredString(tree, child, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final TypeInfo typeInfo = isConstructor ? TypeInfo.createConstructorType() : TypeInfo.create(tree, node, parentStub);
|
||||
final boolean isAnno = (node.getTokenType() == JavaElementType.ANNOTATION_METHOD);
|
||||
final byte flags = PsiMethodStubImpl.packFlags(isConstructor, isAnno, isVarArgs, isDeprecatedByComment, hasDeprecatedAnnotation);
|
||||
TypeInfo typeInfo = isConstructor ? TypeInfo.createConstructorType() : TypeInfo.create(tree, node, parentStub);
|
||||
boolean isAnno = (node.getTokenType() == JavaElementType.ANNOTATION_METHOD);
|
||||
byte flags = PsiMethodStubImpl.packFlags(isConstructor, isAnno, isVarArgs, isDeprecatedByComment, hasDeprecatedAnnotation);
|
||||
|
||||
final PsiMethodStubImpl stub = new PsiMethodStubImpl(parentStub, StringRef.fromString(name), typeInfo, flags, StringRef.fromString(defValueText));
|
||||
stub.setExtensionMethodMark(isExtension);
|
||||
return stub;
|
||||
return new PsiMethodStubImpl(parentStub, StringRef.fromString(name), typeInfo, flags, StringRef.fromString(defValueText));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-5
@@ -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.
|
||||
@@ -24,8 +24,8 @@ import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
|
||||
import com.intellij.psi.impl.java.stubs.PsiAnnotationStub;
|
||||
import com.intellij.psi.stubs.StubBase;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.PatchedSoftReference;
|
||||
import com.intellij.util.io.StringRef;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -38,7 +38,7 @@ public class PsiAnnotationStubImpl extends StubBase<PsiAnnotation> implements Ps
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.java.stubs.impl.PsiAnnotationStubImpl");
|
||||
|
||||
private final String myText;
|
||||
private PatchedSoftReference<PsiAnnotation> myParsedFromRepository;
|
||||
private SoftReference<PsiAnnotation> myParsedFromRepository;
|
||||
|
||||
public PsiAnnotationStubImpl(final StubElement parent, final String text) {
|
||||
this(parent, text, null);
|
||||
@@ -73,8 +73,7 @@ public class PsiAnnotationStubImpl extends StubBase<PsiAnnotation> implements Ps
|
||||
try {
|
||||
PsiJavaParserFacade facade = JavaPsiFacade.getInstance(getProject()).getParserFacade();
|
||||
PsiAnnotation annotation = facade.createAnnotationFromText(text, getPsi());
|
||||
myParsedFromRepository = new PatchedSoftReference<PsiAnnotation>(annotation);
|
||||
assert annotation != null : text;
|
||||
myParsedFromRepository = new SoftReference<PsiAnnotation>(annotation);
|
||||
return annotation;
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
|
||||
+4
-4
@@ -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.
|
||||
@@ -28,15 +28,15 @@ import com.intellij.psi.impl.java.stubs.PsiImportStatementStub;
|
||||
import com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl;
|
||||
import com.intellij.psi.stubs.StubBase;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.PatchedSoftReference;
|
||||
import com.intellij.util.io.StringRef;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PsiImportStatementStubImpl extends StubBase<PsiImportStatementBase> implements PsiImportStatementStub {
|
||||
private final byte myFlags;
|
||||
private final StringRef myText;
|
||||
private PatchedSoftReference<PsiJavaCodeReferenceElement> myReference = null;
|
||||
private SoftReference<PsiJavaCodeReferenceElement> myReference = null;
|
||||
|
||||
private final static int ON_DEMAND = 0x01;
|
||||
private final static int STATIC = 0x02;
|
||||
@@ -80,7 +80,7 @@ public class PsiImportStatementStubImpl extends StubBase<PsiImportStatementBase>
|
||||
PsiJavaCodeReferenceElement ref = myReference != null ? myReference.get() : null;
|
||||
if (ref == null) {
|
||||
ref = isStatic() ? getStaticReference() : getRegularReference();
|
||||
myReference = new PatchedSoftReference<PsiJavaCodeReferenceElement>(ref);
|
||||
myReference = new SoftReference<PsiJavaCodeReferenceElement>(ref);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
+1
-11
@@ -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.
|
||||
@@ -37,8 +37,6 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
|
||||
private final byte myFlags;
|
||||
private final StringRef myName;
|
||||
private StringRef myDefaultValueText;
|
||||
// todo[r.sh] drop this after transition period finished
|
||||
private boolean myHasExtMethodMark = false;
|
||||
|
||||
private static final int CONSTRUCTOR = 0x01;
|
||||
private static final int VARARGS = 0x02;
|
||||
@@ -74,14 +72,6 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
|
||||
myReturnType = returnType;
|
||||
}
|
||||
|
||||
public void setExtensionMethodMark(boolean hasExtMethodMark) {
|
||||
myHasExtMethodMark = hasExtMethodMark;
|
||||
}
|
||||
|
||||
public boolean hasExtensionMethodMark() {
|
||||
return myHasExtMethodMark;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConstructor() {
|
||||
return (myFlags & CONSTRUCTOR) != 0;
|
||||
|
||||
@@ -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,79 +15,133 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.source;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.LighterAST;
|
||||
import com.intellij.lang.LighterASTNode;
|
||||
import com.intellij.lang.impl.ASTNodeBuilder;
|
||||
import com.intellij.lang.LighterLazyParseableNode;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiJavaFile;
|
||||
import com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.impl.source.tree.LightTreeUtil;
|
||||
import com.intellij.psi.impl.source.tree.SourceUtil;
|
||||
import com.intellij.psi.impl.source.tree.*;
|
||||
import com.intellij.psi.stubs.LightStubBuilder;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.io.StringRef;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class JavaLightStubBuilder extends LightStubBuilder {
|
||||
@NotNull
|
||||
@Override
|
||||
protected StubElement createStubForFile(final PsiFile file, final LighterAST tree) {
|
||||
if (!(file instanceof PsiJavaFile)) return super.createStubForFile(file, tree);
|
||||
|
||||
String refText = "";
|
||||
|
||||
final LighterASTNode pkg = LightTreeUtil.firstChildOfType(tree, tree.getRoot(), JavaElementType.PACKAGE_STATEMENT);
|
||||
if (pkg != null) {
|
||||
final LighterASTNode ref = LightTreeUtil.firstChildOfType(tree, pkg, JavaElementType.JAVA_CODE_REFERENCE);
|
||||
if (ref != null) {
|
||||
refText = SourceUtil.getTextSkipWhiteSpaceAndComments(tree, ref);
|
||||
}
|
||||
protected StubElement createStubForFile(@NotNull PsiFile file, @NotNull LighterAST tree) {
|
||||
if (!(file instanceof PsiJavaFile)) {
|
||||
return super.createStubForFile(file, tree);
|
||||
}
|
||||
|
||||
String refText = "";
|
||||
LighterASTNode pkg = LightTreeUtil.firstChildOfType(tree, tree.getRoot(), JavaElementType.PACKAGE_STATEMENT);
|
||||
if (pkg != null) {
|
||||
LighterASTNode ref = LightTreeUtil.firstChildOfType(tree, pkg, JavaElementType.JAVA_CODE_REFERENCE);
|
||||
if (ref != null) {
|
||||
refText = SourceUtil.getReferenceText(tree, ref);
|
||||
}
|
||||
}
|
||||
return new PsiJavaFileStubImpl((PsiJavaFile)file, StringRef.fromString(refText), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean skipChildProcessingWhenBuildingStubs(final IElementType nodeType, final IElementType childType) {
|
||||
return childType == JavaElementType.PARAMETER && nodeType != JavaElementType.PARAMETER_LIST ||
|
||||
childType == JavaElementType.PARAMETER_LIST && nodeType == JavaElementType.LAMBDA_EXPRESSION;
|
||||
public boolean skipChildProcessingWhenBuildingStubs(@NotNull ASTNode parent, @NotNull ASTNode node) {
|
||||
IElementType parentType = parent.getElementType();
|
||||
IElementType nodeType = node.getElementType();
|
||||
|
||||
if (checkByTypes(parentType, nodeType)) return true;
|
||||
|
||||
if (nodeType == JavaElementType.CODE_BLOCK && node instanceof TreeElement) {
|
||||
CodeBlockVisitor visitor = new CodeBlockVisitor();
|
||||
((TreeElement)node).acceptTree(visitor);
|
||||
return visitor.result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean skipChildProcessingWhenBuildingStubs(final LightStubBuilder builder,
|
||||
final LighterAST tree,
|
||||
final LighterASTNode parent,
|
||||
final LighterASTNode child) {
|
||||
if (child.getTokenType() == JavaElementType.CODE_BLOCK) {
|
||||
if (child instanceof ASTNodeBuilder.ASTUnparsedNodeMarker) {
|
||||
ASTNodeBuilder.ASTUnparsedNodeMarker nodeMarker = (ASTNodeBuilder.ASTUnparsedNodeMarker)child;
|
||||
final ASTNodeBuilder nodeBuilder = nodeMarker.getBuilder();
|
||||
final int endLexemeIndex = nodeMarker.getEndLexemeIndex();
|
||||
boolean seenNew = false;
|
||||
protected boolean skipChildProcessingWhenBuildingStubs(@NotNull LighterAST tree, @NotNull LighterASTNode parent, @NotNull LighterASTNode node) {
|
||||
IElementType parentType = parent.getTokenType();
|
||||
IElementType nodeType = node.getTokenType();
|
||||
|
||||
for (int i = nodeMarker.getStartLexemeIndex(); i < endLexemeIndex; ++i) {
|
||||
final IElementType type = nodeBuilder.getElementType(i);
|
||||
if (type == JavaTokenType.NEW_KEYWORD) {
|
||||
seenNew = true;
|
||||
}
|
||||
else if (seenNew && type == JavaTokenType.LBRACE) {
|
||||
return false;
|
||||
}
|
||||
else if (seenNew && type == JavaTokenType.SEMICOLON) {
|
||||
seenNew = false;
|
||||
}
|
||||
else if (type == JavaTokenType.AT || // local vars can be annotated and we have them in stubs!
|
||||
type == JavaTokenType.CLASS_KEYWORD || // local classes
|
||||
type == JavaTokenType.INTERFACE_KEYWORD ||
|
||||
type == JavaTokenType.ENUM_KEYWORD) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (checkByTypes(parentType, nodeType)) return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
if (nodeType == JavaElementType.CODE_BLOCK && node instanceof LighterLazyParseableNode) {
|
||||
CodeBlockVisitor visitor = new CodeBlockVisitor();
|
||||
((LighterLazyParseableNode)node).accept(visitor);
|
||||
return visitor.result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkByTypes(IElementType parentType, IElementType nodeType) {
|
||||
if (ElementType.IMPORT_STATEMENT_BASE_BIT_SET.contains(parentType)) {
|
||||
return true;
|
||||
}
|
||||
if (nodeType == JavaElementType.PARAMETER && parentType != JavaElementType.PARAMETER_LIST) {
|
||||
return true;
|
||||
}
|
||||
if (nodeType == JavaElementType.PARAMETER_LIST && parentType == JavaElementType.LAMBDA_EXPRESSION) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class CodeBlockVisitor extends RecursiveTreeElementWalkingVisitor implements LighterLazyParseableNode.Visitor {
|
||||
private static final TokenSet BLOCK_ELEMENTS = TokenSet.create(
|
||||
JavaElementType.ANNOTATION, JavaElementType.CLASS, JavaElementType.ANONYMOUS_CLASS);
|
||||
|
||||
private boolean result = true;
|
||||
|
||||
@Override
|
||||
protected void visitNode(TreeElement element) {
|
||||
if (BLOCK_ELEMENTS.contains(element.getElementType())) {
|
||||
result = false;
|
||||
stopWalking();
|
||||
return;
|
||||
}
|
||||
super.visitNode(element);
|
||||
}
|
||||
|
||||
private IElementType last = null;
|
||||
private boolean seenNew = false;
|
||||
|
||||
@Override
|
||||
public boolean visit(IElementType type) {
|
||||
if (ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET.contains(type)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// annotations
|
||||
if (type == JavaTokenType.AT) {
|
||||
return (result = false);
|
||||
}
|
||||
// anonymous classes
|
||||
else if (type == JavaTokenType.NEW_KEYWORD) {
|
||||
seenNew = true;
|
||||
}
|
||||
else if (seenNew && type == JavaTokenType.SEMICOLON) {
|
||||
seenNew = false;
|
||||
}
|
||||
else if (seenNew && type == JavaTokenType.LBRACE && last != JavaTokenType.RBRACKET) {
|
||||
return (result = false);
|
||||
}
|
||||
// local classes
|
||||
else if (type == JavaTokenType.CLASS_KEYWORD && last != JavaTokenType.DOT) {
|
||||
return (result = false);
|
||||
}
|
||||
|
||||
last = type;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -22,7 +22,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
|
||||
import com.intellij.psi.impl.java.stubs.PsiMethodStub;
|
||||
import com.intellij.psi.impl.source.tree.ChildRole;
|
||||
import com.intellij.util.PatchedSoftReference;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author ven
|
||||
*/
|
||||
public class PsiAnnotationMethodImpl extends PsiMethodImpl implements PsiAnnotationMethod {
|
||||
private PatchedSoftReference<PsiAnnotationMemberValue> myCachedDefaultValue = null;
|
||||
private SoftReference<PsiAnnotationMemberValue> myCachedDefaultValue = null;
|
||||
|
||||
public PsiAnnotationMethodImpl(final PsiMethodStub stub) {
|
||||
super(stub, JavaStubElementTypes.ANNOTATION_METHOD);
|
||||
@@ -68,7 +68,7 @@ public class PsiAnnotationMethodImpl extends PsiMethodImpl implements PsiAnnotat
|
||||
final PsiFileFactory factory = PsiFileFactory.getInstance(getProject());
|
||||
final PsiJavaFile file = (PsiJavaFile)factory.createFileFromText("a.java", JavaFileType.INSTANCE, annoText);
|
||||
final PsiAnnotationMemberValue value = ((PsiAnnotationMethod)file.getClasses()[0].getMethods()[0]).getDefaultValue();
|
||||
myCachedDefaultValue = new PatchedSoftReference<PsiAnnotationMemberValue>(value);
|
||||
myCachedDefaultValue = new SoftReference<PsiAnnotationMemberValue>(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -22,12 +22,12 @@ import com.intellij.psi.impl.java.stubs.PsiClassStub;
|
||||
import com.intellij.psi.impl.source.tree.ChildRole;
|
||||
import com.intellij.psi.impl.source.tree.SharedImplUtil;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.PatchedSoftReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PsiAnonymousClassImpl extends PsiClassImpl implements PsiAnonymousClass {
|
||||
private PatchedSoftReference<PsiClassType> myCachedBaseType = null;
|
||||
private SoftReference<PsiClassType> myCachedBaseType = null;
|
||||
|
||||
public PsiAnonymousClassImpl(final PsiClassStub stub) {
|
||||
super(stub, JavaStubElementTypes.ANONYMOUS_CLASS);
|
||||
@@ -92,7 +92,7 @@ public class PsiAnonymousClassImpl extends PsiClassImpl implements PsiAnonymousC
|
||||
type = PsiType.getJavaLangObject(getManager(), getResolveScope());
|
||||
}
|
||||
|
||||
myCachedBaseType = new PatchedSoftReference<PsiClassType>(type);
|
||||
myCachedBaseType = new SoftReference<PsiClassType>(type);
|
||||
return type;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -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.
|
||||
@@ -33,9 +33,9 @@ import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.stubs.IStubElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.ui.RowIcon;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.PatchedSoftReference;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -49,7 +49,7 @@ import java.util.Set;
|
||||
public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements PsiField, PsiVariableEx, Queryable {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiFieldImpl");
|
||||
|
||||
private volatile PatchedSoftReference<PsiType> myCachedType = null;
|
||||
private volatile SoftReference<PsiType> myCachedType = null;
|
||||
private volatile Object myCachedInitializerValue = null; // PsiExpression on constant value for literal
|
||||
|
||||
public PsiFieldImpl(final PsiFieldStub stub) {
|
||||
@@ -129,7 +129,7 @@ public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements Ps
|
||||
String typeText = TypeInfo.createTypeText(stub.getType(false));
|
||||
try {
|
||||
final PsiType type = JavaPsiFacade.getInstance(getProject()).getParserFacade().createTypeFromText(typeText, this);
|
||||
myCachedType = new PatchedSoftReference<PsiType>(type);
|
||||
myCachedType = new SoftReference<PsiType>(type);
|
||||
return type;
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
@@ -148,7 +148,7 @@ public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements Ps
|
||||
public PsiType getType(){
|
||||
final PsiFieldStub stub = getStub();
|
||||
if (stub != null) {
|
||||
PatchedSoftReference<PsiType> cachedType = myCachedType;
|
||||
SoftReference<PsiType> cachedType = myCachedType;
|
||||
if (cachedType != null) {
|
||||
PsiType type = cachedType.get();
|
||||
if (type != null) return type;
|
||||
@@ -157,7 +157,7 @@ public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements Ps
|
||||
String typeText = TypeInfo.createTypeText(stub.getType(true));
|
||||
try {
|
||||
final PsiType type = JavaPsiFacade.getInstance(getProject()).getParserFacade().createTypeFromText(typeText, this);
|
||||
myCachedType = new PatchedSoftReference<PsiType>(type);
|
||||
myCachedType = new SoftReference<PsiType>(type);
|
||||
return type;
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
|
||||
@@ -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.
|
||||
@@ -20,8 +20,10 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
|
||||
import com.intellij.psi.impl.java.stubs.PsiImportListStub;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.ArrayFactory;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -63,17 +65,19 @@ public class PsiImportListImpl extends JavaStubPsiElement<PsiImportListStub> imp
|
||||
super.subtreeChanged();
|
||||
}
|
||||
|
||||
private static final TokenSet IMPORT_STATEMENT_BIT_SET = TokenSet.create(JavaElementType.IMPORT_STATEMENT);
|
||||
private static final TokenSet IMPORT_STATIC_STATEMENT_BIT_SET = TokenSet.create(JavaElementType.IMPORT_STATIC_STATEMENT);
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiImportStatement[] getImportStatements() {
|
||||
return getStubOrPsiChildren(ElementType.IMPORT_STATEMENT_BIT_SET, PsiImportStatementImpl.ARRAY_FACTORY);
|
||||
return getStubOrPsiChildren(IMPORT_STATEMENT_BIT_SET, PsiImportStatementImpl.ARRAY_FACTORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiImportStaticStatement[] getImportStaticStatements() {
|
||||
return getStubOrPsiChildren(ElementType.IMPORT_STATIC_STATEMENT_BIT_SET, PsiImportStaticStatementImpl.ARRAY_FACTORY);
|
||||
|
||||
return getStubOrPsiChildren(IMPORT_STATIC_STATEMENT_BIT_SET, PsiImportStaticStatementImpl.ARRAY_FACTORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -686,7 +686,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
|
||||
private String getTextSkipWhiteSpaceAndComments() {
|
||||
String whiteSpaceAndComments = myCachedTextSkipWhiteSpaceAndComments;
|
||||
if (whiteSpaceAndComments == null) {
|
||||
myCachedTextSkipWhiteSpaceAndComments = whiteSpaceAndComments = SourceUtil.getTextSkipWhiteSpaceAndComments(this);
|
||||
myCachedTextSkipWhiteSpaceAndComments = whiteSpaceAndComments = SourceUtil.getReferenceText(this);
|
||||
}
|
||||
return whiteSpaceAndComments;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -40,9 +40,9 @@ import com.intellij.psi.stubs.IStubElementType;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.ui.RowIcon;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.PatchedSoftReference;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -53,7 +53,7 @@ import java.util.Map;
|
||||
public class PsiMethodImpl extends JavaStubPsiElement<PsiMethodStub> implements PsiMethod, Queryable {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiMethodImpl");
|
||||
|
||||
private PatchedSoftReference<PsiType> myCachedType = null;
|
||||
private SoftReference<PsiType> myCachedType = null;
|
||||
|
||||
public PsiMethodImpl(final PsiMethodStub stub) {
|
||||
this(stub, JavaStubElementTypes.METHOD);
|
||||
@@ -220,7 +220,7 @@ public class PsiMethodImpl extends JavaStubPsiElement<PsiMethodStub> implements
|
||||
final String typeText = TypeInfo.createTypeText(stub.getReturnTypeText(true));
|
||||
if (typeText == null) return null;
|
||||
|
||||
PatchedSoftReference<PsiType> cachedType = myCachedType;
|
||||
SoftReference<PsiType> cachedType = myCachedType;
|
||||
if (cachedType != null) {
|
||||
PsiType type = cachedType.get();
|
||||
if (type != null) return type;
|
||||
@@ -228,7 +228,7 @@ public class PsiMethodImpl extends JavaStubPsiElement<PsiMethodStub> implements
|
||||
|
||||
try {
|
||||
final PsiType type = JavaPsiFacade.getInstance(getProject()).getElementFactory().createTypeFromText(typeText, this);
|
||||
myCachedType = new PatchedSoftReference<PsiType>(type);
|
||||
myCachedType = new SoftReference<PsiType>(type);
|
||||
return type;
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,15 +30,12 @@ import com.intellij.psi.impl.source.tree.Factory;
|
||||
import com.intellij.psi.impl.source.tree.TreeElement;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -134,12 +131,9 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
||||
return false;
|
||||
}
|
||||
if (type == JavaTokenType.ABSTRACT_KEYWORD) {
|
||||
return !(getNode().findChildByType(JavaTokenType.DEFAULT_KEYWORD) != null || findExtensionMethodMarker((PsiMethod)parent) != null);
|
||||
return getNode().findChildByType(JavaTokenType.DEFAULT_KEYWORD) == null;
|
||||
}
|
||||
}
|
||||
if (type == JavaTokenType.DEFAULT_KEYWORD && findExtensionMethodMarker((PsiMethod)parent) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (parent instanceof PsiField) {
|
||||
if (parent instanceof PsiEnumConstant) {
|
||||
@@ -179,16 +173,6 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
||||
return getNode().findChildByType(type) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiJavaToken findExtensionMethodMarker(@Nullable PsiMethod method) {
|
||||
// todo[r.sh] drop this after transition period finished
|
||||
if (method == null) return null;
|
||||
final PsiCodeBlock body = method.getBody();
|
||||
if (body == null) return null;
|
||||
final PsiElement previous = PsiTreeUtil.skipSiblingsBackward(body, PsiComment.class, PsiWhiteSpace.class);
|
||||
return previous instanceof PsiJavaToken && PsiUtil.isJavaToken(previous, JavaTokenType.DEFAULT_KEYWORD) ? (PsiJavaToken)previous : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasExplicitModifier(@NotNull String name) {
|
||||
final CompositeElement tree = (CompositeElement)getNode();
|
||||
@@ -234,7 +218,6 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
||||
}
|
||||
else if (parent instanceof PsiMethod && grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) {
|
||||
if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.ABSTRACT_KEYWORD) return;
|
||||
if (type == JavaTokenType.DEFAULT_KEYWORD && findExtensionMethodMarker((PsiMethod)parent) != null) return;
|
||||
}
|
||||
else if (parent instanceof PsiClass && grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) {
|
||||
if (type == JavaTokenType.PUBLIC_KEYWORD) return;
|
||||
@@ -257,13 +240,6 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
||||
if (child != null) {
|
||||
SourceTreeToPsiMap.treeToPsiNotNull(child).delete();
|
||||
}
|
||||
|
||||
if (type == JavaTokenType.DEFAULT_KEYWORD && parent instanceof PsiMethod) {
|
||||
final PsiJavaToken marker = findExtensionMethodMarker((PsiMethod)parent);
|
||||
if (marker != null) {
|
||||
marker.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@ import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.stubs.IStubElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.ui.RowIcon;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.PatchedSoftReference;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -44,7 +44,7 @@ import java.util.Arrays;
|
||||
public class PsiParameterImpl extends JavaStubPsiElement<PsiParameterStub> implements PsiParameter {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiParameterImpl");
|
||||
|
||||
private volatile PatchedSoftReference<PsiType> myCachedType = null;
|
||||
private volatile SoftReference<PsiType> myCachedType = null;
|
||||
|
||||
public PsiParameterImpl(@NotNull PsiParameterStub stub) {
|
||||
this(stub, JavaStubElementTypes.PARAMETER);
|
||||
@@ -116,7 +116,7 @@ public class PsiParameterImpl extends JavaStubPsiElement<PsiParameterStub> imple
|
||||
public PsiType getType() {
|
||||
PsiParameterStub stub = getStub();
|
||||
if (stub != null) {
|
||||
PatchedSoftReference<PsiType> cachedType = myCachedType;
|
||||
SoftReference<PsiType> cachedType = myCachedType;
|
||||
if (cachedType != null) {
|
||||
PsiType type = cachedType.get();
|
||||
if (type != null) return type;
|
||||
@@ -126,7 +126,7 @@ public class PsiParameterImpl extends JavaStubPsiElement<PsiParameterStub> imple
|
||||
assert typeText != null : stub;
|
||||
try {
|
||||
PsiType type = JavaPsiFacade.getInstance(getProject()).getParserFacade().createTypeFromText(typeText, this);
|
||||
myCachedType = new PatchedSoftReference<PsiType>(type);
|
||||
myCachedType = new SoftReference<PsiType>(type);
|
||||
return type;
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
|
||||
@@ -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.
|
||||
@@ -28,9 +28,9 @@ import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.PatchedSoftReference;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -45,7 +45,7 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiTypeElementImpl");
|
||||
|
||||
private volatile PsiType myCachedType = null;
|
||||
private volatile PatchedSoftReference<PsiType> myCachedDetachedType = null;
|
||||
private volatile SoftReference<PsiType> myCachedDetachedType = null;
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public PsiTypeElementImpl() {
|
||||
@@ -110,8 +110,8 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
||||
final List<PsiType> types = ContainerUtil.map(typeElements, new Function<PsiTypeElement, PsiType>() {
|
||||
@Override public PsiType fun(final PsiTypeElement psiTypeElement) { return psiTypeElement.getType(); }
|
||||
});
|
||||
cachedType = opElement instanceof PsiJavaToken && ((PsiJavaToken)opElement).getTokenType() == JavaTokenType.AND
|
||||
? PsiIntersectionType.createIntersection(types.toArray(new PsiType[types.size()]))
|
||||
cachedType = opElement instanceof PsiJavaToken && ((PsiJavaToken)opElement).getTokenType() == JavaTokenType.AND
|
||||
? PsiIntersectionType.createIntersection(types.toArray(new PsiType[types.size()]))
|
||||
: new PsiDisjunctionType(types, getManager());
|
||||
}
|
||||
}
|
||||
@@ -168,14 +168,14 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
||||
}
|
||||
|
||||
public PsiType getDetachedType(@NotNull PsiElement context) {
|
||||
PatchedSoftReference<PsiType> cached = myCachedDetachedType;
|
||||
SoftReference<PsiType> cached = myCachedDetachedType;
|
||||
PsiType type = cached == null ? null : cached.get();
|
||||
if (type != null) return type;
|
||||
try {
|
||||
String combinedAnnotations = getCombinedAnnotationsText();
|
||||
String text = combinedAnnotations.isEmpty() ? getText().trim() : combinedAnnotations + " " + getText().trim();
|
||||
type = JavaPsiFacade.getInstance(getProject()).getElementFactory().createTypeFromText(text, context);
|
||||
myCachedDetachedType = new PatchedSoftReference<PsiType>(type);
|
||||
myCachedDetachedType = new SoftReference<PsiType>(type);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
return getType();
|
||||
|
||||
+3
-2
@@ -19,6 +19,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.scope.MethodProcessorSetupFailedException;
|
||||
import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
@@ -99,8 +100,8 @@ public class GraphInferencePolicy extends ProcessCandidateParameterTypeInference
|
||||
}
|
||||
|
||||
public static void forget(PsiElement parent) {
|
||||
if (parent instanceof PsiCallExpression) {
|
||||
final PsiElement gParent = parent.getParent();
|
||||
if (parent instanceof PsiExpression) {
|
||||
PsiElement gParent = PsiUtil.skipParenthesizedExprUp(parent.getParent());
|
||||
if (gParent instanceof PsiExpressionList) {
|
||||
final PsiElement ggParent = gParent.getParent();
|
||||
if (ggParent instanceof PsiCallExpression) {
|
||||
|
||||
+5
-1
@@ -43,7 +43,11 @@ public class ProcessCandidateParameterTypeInferencePolicy extends DefaultParamet
|
||||
PsiCallExpression contextCall,
|
||||
PsiTypeParameter typeParameter) {
|
||||
PsiExpression[] expressions = expressionList.getExpressions();
|
||||
int i = ArrayUtil.find(expressions, innerMethodCall);
|
||||
PsiElement parent = innerMethodCall;
|
||||
while (parent.getParent() instanceof PsiParenthesizedExpression) {
|
||||
parent = parent.getParent();
|
||||
}
|
||||
int i = ArrayUtil.find(expressions, parent);
|
||||
if (i < 0) return null;
|
||||
PsiMethod owner = (PsiMethod)typeParameter.getOwner();
|
||||
if (owner == null) return null;
|
||||
|
||||
+116
-4
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.source.resolve;
|
||||
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
@@ -32,6 +34,7 @@ import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
|
||||
import com.intellij.psi.scope.processor.MethodResolverProcessor;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
@@ -205,6 +208,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
sortLambdaExpressionsLast(paramTypes, argTypes);
|
||||
boolean rawType = false;
|
||||
boolean nullPassed = false;
|
||||
boolean lambdaRaw = false;
|
||||
for (int j = 0; j < argTypes.length; j++) {
|
||||
PsiType argumentType = argTypes[j];
|
||||
if (argumentType == null) continue;
|
||||
@@ -228,6 +232,12 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
if (currentSubstitution == FAILED_INFERENCE || (currentSubstitution == null && lowerBound == PsiType.NULL)) return RAW_INFERENCE;
|
||||
}
|
||||
if (nullPassed && currentSubstitution == null) return RAW_INFERENCE;
|
||||
if (currentSubstitution != null && currentSubstitution.first == null) {
|
||||
lambdaRaw = true;
|
||||
}
|
||||
if (currentSubstitution == null && lambdaRaw) {
|
||||
return new Pair<PsiType, ConstraintType>(PsiType.getJavaLangObject(typeParameter.getManager(), typeParameter.getResolveScope()), ConstraintType.EQUALS);
|
||||
}
|
||||
} else if (argumentType instanceof PsiMethodReferenceType) {
|
||||
final PsiMethodReferenceExpression referenceExpression = ((PsiMethodReferenceType)argumentType).getExpression();
|
||||
currentSubstitution = inferConstraintFromFunctionalInterfaceMethod(typeParameter, referenceExpression, partialSubstitutor.substitute(parameterType), partialSubstitutor, policy);
|
||||
@@ -998,7 +1008,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferMethodTypeParameterFromParent(PsiElement parent,
|
||||
private static Pair<PsiType, ConstraintType> inferMethodTypeParameterFromParent(final PsiElement parent,
|
||||
PsiExpression methodCall,
|
||||
final PsiTypeParameter typeParameter,
|
||||
PsiSubstitutor substitutor,
|
||||
@@ -1065,15 +1075,28 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
}
|
||||
} else if (parent instanceof PsiLambdaExpression) {
|
||||
expectedType = LambdaUtil.getFunctionalInterfaceReturnType(((PsiLambdaExpression)parent).getFunctionalInterfaceType());
|
||||
expectedType = ourGraphGuard.doPreventingRecursion(methodCall, true, new Computable<PsiType>() {
|
||||
@Override
|
||||
public PsiType compute() {
|
||||
return LambdaUtil.getFunctionalInterfaceReturnType(((PsiLambdaExpression)parent).getFunctionalInterfaceType());
|
||||
}
|
||||
});
|
||||
if (expectedType == null) {
|
||||
return getFailedInferenceConstraint(typeParameter);
|
||||
return null;
|
||||
}
|
||||
} else if (parent instanceof PsiTypeCastExpression) {
|
||||
expectedType = ((PsiTypeCastExpression)parent).getType();
|
||||
} else if (parent instanceof PsiConditionalExpression) {
|
||||
if (PsiUtil.isLanguageLevel8OrHigher(parent)) {
|
||||
return inferMethodTypeParameterFromParent(parent.getParent(), (PsiExpression)parent, typeParameter, substitutor, policy);
|
||||
try {
|
||||
final Pair<PsiType, ConstraintType> pair = inferFromConditionalExpression(parent, methodCall, typeParameter, substitutor, policy);
|
||||
if (pair != null) {
|
||||
return pair;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
GraphInferencePolicy.forget(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1127,6 +1150,10 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
final Pair<PsiType, ConstraintType> inferredExceptionTypeConstraint = inferExceptionConstrains(typeParameter, expression, method, resolveResult.getSubstitutor());
|
||||
if (inferredExceptionTypeConstraint != null) {
|
||||
return inferredExceptionTypeConstraint;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1170,6 +1197,91 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferExceptionConstrains(PsiTypeParameter typeParameter,
|
||||
PsiExpression expression,
|
||||
PsiMethod method,
|
||||
PsiSubstitutor substitutor) {
|
||||
final PsiClassType[] declaredExceptions = method.getThrowsList().getReferencedTypes();
|
||||
for (PsiClassType exception : declaredExceptions) {
|
||||
final PsiType substitute = substitutor.substitute(exception);
|
||||
if (PsiUtil.resolveClassInType(substitute) == typeParameter) {
|
||||
if (expression instanceof PsiLambdaExpression) {
|
||||
final PsiElement body = ((PsiLambdaExpression)expression).getBody();
|
||||
if (body != null) {
|
||||
final List<PsiClassType> unhandledExceptions = ExceptionUtil.getUnhandledExceptions(body);
|
||||
if (unhandledExceptions.isEmpty()) {
|
||||
return inferUncheckedException(typeParameter, exception, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (expression instanceof PsiMethodReferenceExpression) {
|
||||
final PsiElement resolve = ((PsiMethodReferenceExpression)expression).resolve();
|
||||
if (resolve instanceof PsiMethod) {
|
||||
final PsiClassType[] declaredThrowsList = ((PsiMethod)resolve).getThrowsList().getReferencedTypes();
|
||||
for (PsiClassType psiClassType : declaredThrowsList) {
|
||||
if (!ExceptionUtil.isUncheckedException(psiClassType)) return null;
|
||||
}
|
||||
return inferUncheckedException(typeParameter, exception, method);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferUncheckedException(PsiTypeParameter typeParameter,
|
||||
PsiClassType exception,
|
||||
PsiMethod method) {
|
||||
final Project project = typeParameter.getProject();
|
||||
final PsiClass runtimeException = JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION, method.getResolveScope());
|
||||
if (runtimeException != null) {
|
||||
for (PsiType superType : exception.getSuperTypes()) {
|
||||
if (!InheritanceUtil.isInheritorOrSelf(runtimeException, PsiUtil.resolveClassInType(superType), true)) {
|
||||
return getFailedInferenceConstraint(typeParameter);
|
||||
}
|
||||
}
|
||||
return Pair.<PsiType, ConstraintType>create(JavaPsiFacade.getElementFactory(project).createType(runtimeException, PsiSubstitutor.EMPTY), ConstraintType.EQUALS);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferFromConditionalExpression(PsiElement parent,
|
||||
PsiExpression methodCall,
|
||||
PsiTypeParameter typeParameter,
|
||||
PsiSubstitutor substitutor,
|
||||
ParameterTypeInferencePolicy policy) {
|
||||
Pair<PsiType, ConstraintType> pair =
|
||||
inferMethodTypeParameterFromParent(PsiUtil.skipParenthesizedExprUp(parent.getParent()), (PsiExpression)parent, typeParameter, substitutor, policy);
|
||||
if (pair == null) {
|
||||
final PsiExpression thenExpression = ((PsiConditionalExpression)parent).getThenExpression();
|
||||
final PsiExpression elseExpression = ((PsiConditionalExpression)parent).getElseExpression();
|
||||
final PsiType[] paramTypes = {((PsiMethod)typeParameter.getOwner()).getReturnType()};
|
||||
if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(elseExpression)) && thenExpression != null) {
|
||||
final PsiType thenType = ourGraphGuard.doPreventingRecursion(parent, true, new Computable<PsiType>() {
|
||||
@Override
|
||||
public PsiType compute() {
|
||||
return thenExpression.getType();
|
||||
}
|
||||
});
|
||||
if (thenType != null) {
|
||||
pair = inferTypeForMethodTypeParameterInner(typeParameter, paramTypes, new PsiType[] {thenType}, substitutor, null, policy);
|
||||
}
|
||||
} else if (methodCall.equals(PsiUtil.skipParenthesizedExprDown(thenExpression)) && elseExpression != null) {
|
||||
final PsiType elseType = ourGraphGuard.doPreventingRecursion(parent, true, new Computable<PsiType>() {
|
||||
@Override
|
||||
public PsiType compute() {
|
||||
return elseExpression.getType();
|
||||
}
|
||||
});
|
||||
if (elseType != null) {
|
||||
pair = inferTypeForMethodTypeParameterInner(typeParameter, paramTypes, new PsiType[] {elseType}, substitutor, null, policy);
|
||||
}
|
||||
}
|
||||
}
|
||||
return pair;
|
||||
}
|
||||
|
||||
private static final ProcessCandidateParameterTypeInferencePolicy GRAPH_INFERENCE_POLICY = new GraphInferencePolicy();
|
||||
|
||||
private static Pair<PsiType, ConstraintType> graphInferenceFromCallContext(@NotNull final PsiExpression methodCall,
|
||||
|
||||
@@ -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.
|
||||
@@ -70,12 +70,8 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen
|
||||
WHILE_STATEMENT, FOR_STATEMENT, FOREACH_STATEMENT, DO_WHILE_STATEMENT, SWITCH_STATEMENT, SWITCH_LABEL_STATEMENT, BREAK_STATEMENT,
|
||||
CONTINUE_STATEMENT, RETURN_STATEMENT, THROW_STATEMENT, SYNCHRONIZED_STATEMENT, TRY_STATEMENT, LABELED_STATEMENT, ASSERT_STATEMENT);
|
||||
|
||||
TokenSet TYPES_BIT_SET = TokenSet.create(TYPE);
|
||||
TokenSet IMPORT_STATEMENT_BIT_SET = TokenSet.create(IMPORT_STATEMENT);
|
||||
TokenSet IMPORT_STATIC_STATEMENT_BIT_SET = TokenSet.create(IMPORT_STATIC_STATEMENT);
|
||||
TokenSet IMPORT_STATEMENT_BASE_BIT_SET = TokenSet.create(IMPORT_STATEMENT, IMPORT_STATIC_STATEMENT);
|
||||
TokenSet CLASS_KEYWORD_BIT_SET = TokenSet.create(CLASS_KEYWORD, INTERFACE_KEYWORD, ENUM_KEYWORD);
|
||||
TokenSet MEMBER_BIT_SET = TokenSet.create(CLASS, FIELD, ENUM_CONSTANT, METHOD, ANNOTATION_METHOD);
|
||||
TokenSet FULL_MEMBER_BIT_SET = TokenSet.orSet(MEMBER_BIT_SET, TokenSet.create(CLASS_INITIALIZER));
|
||||
TokenSet ANNOTATIONS = TokenSet.create(ANNOTATION);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -20,30 +20,67 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.LighterAST;
|
||||
import com.intellij.lang.LighterASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.impl.source.DummyHolder;
|
||||
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.CharTable;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SourceUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.SourceUtil");
|
||||
|
||||
private static final TokenSet REF_FILTER = TokenSet.orSet(
|
||||
ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET, TokenSet.create(JavaElementType.ANNOTATION));
|
||||
|
||||
private SourceUtil() { }
|
||||
|
||||
public static String getTextSkipWhiteSpaceAndComments(final ASTNode element) {
|
||||
@NotNull
|
||||
public static String getReferenceText(@NotNull PsiJavaCodeReferenceElement ref) {
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
|
||||
((TreeElement)ref.getNode()).acceptTree(new RecursiveTreeElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitLeaf(LeafElement leaf) {
|
||||
if (!REF_FILTER.contains(leaf.getElementType())) {
|
||||
buffer.append(leaf.getText());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitComposite(CompositeElement composite) {
|
||||
if (!REF_FILTER.contains(composite.getElementType())) {
|
||||
super.visitComposite(composite);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getReferenceText(@NotNull LighterAST tree, @NotNull LighterASTNode node) {
|
||||
return LightTreeUtil.toFilteredString(tree, node, REF_FILTER);
|
||||
}
|
||||
|
||||
/** @deprecated use {@link AstBufferUtil#getTextSkippingWhitespaceComments(ASTNode)} (to remove in IDEA 13) */
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public static String getTextSkipWhiteSpaceAndComments(ASTNode element) {
|
||||
return AstBufferUtil.getTextSkippingWhitespaceComments(element);
|
||||
}
|
||||
|
||||
public static String getTextSkipWhiteSpaceAndComments(final LighterAST tree, final LighterASTNode node) {
|
||||
/** @deprecated use {@link LightTreeUtil#toFilteredString(LighterAST, LighterASTNode, TokenSet)} (to remove in IDEA 13) */
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public static String getTextSkipWhiteSpaceAndComments(LighterAST tree, LighterASTNode node) {
|
||||
return LightTreeUtil.toFilteredString(tree, node, ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET);
|
||||
}
|
||||
|
||||
public static TreeElement addParenthToReplacedChild(final IElementType parenthType, TreeElement newChild, PsiManager manager) {
|
||||
public static TreeElement addParenthToReplacedChild(@NotNull IElementType parenthType,
|
||||
@NotNull TreeElement newChild,
|
||||
@NotNull PsiManager manager) {
|
||||
CompositeElement parenthExpr = ASTFactory.composite(parenthType);
|
||||
|
||||
TreeElement dummyExpr = (TreeElement)newChild.clone();
|
||||
@@ -56,9 +93,8 @@ public class SourceUtil {
|
||||
|
||||
try {
|
||||
CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject());
|
||||
parenthExpr =
|
||||
(CompositeElement)SourceTreeToPsiMap.psiElementToTree(
|
||||
codeStyleManager.reformat(SourceTreeToPsiMap.treeElementToPsi(parenthExpr)));
|
||||
PsiElement formatted = codeStyleManager.reformat(SourceTreeToPsiMap.treeToPsiNotNull(parenthExpr));
|
||||
parenthExpr = (CompositeElement)SourceTreeToPsiMap.psiToTreeNotNull(formatted);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e); // should not happen
|
||||
@@ -68,7 +104,7 @@ public class SourceUtil {
|
||||
dummyExpr.rawReplaceWithList(newChild);
|
||||
|
||||
newChild = parenthExpr;
|
||||
// TODO remove explicit caches drop since this should be ok if we will use ChangeUtil for the modification
|
||||
// TODO remove explicit caches drop since this should be ok if we will use ChangeUtil for the modification
|
||||
TreeUtil.clearCaches(TreeUtil.getFileElement(newChild));
|
||||
return newChild;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -214,7 +214,7 @@ public class ClassElement extends CompositeElement implements Constants {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
super.deleteChildInternal(child);
|
||||
}
|
||||
|
||||
@@ -364,7 +364,7 @@ public class ClassElement extends CompositeElement implements Constants {
|
||||
else if (i == JavaDocElementType.DOC_COMMENT) {
|
||||
return getChildRole(child, ChildRole.DOC_COMMENT);
|
||||
}
|
||||
else if (i == C_STYLE_COMMENT || i == END_OF_LINE_COMMENT) {
|
||||
else if (ElementType.JAVA_PLAIN_COMMENT_BIT_SET.contains(i)) {
|
||||
return ChildRoleBase.NONE;
|
||||
}
|
||||
else if (i == MODIFIER_LIST) {
|
||||
@@ -376,7 +376,7 @@ public class ClassElement extends CompositeElement implements Constants {
|
||||
else if (i == IMPLEMENTS_LIST) {
|
||||
return ChildRole.IMPLEMENTS_LIST;
|
||||
}
|
||||
else if (i == CLASS_KEYWORD || i == INTERFACE_KEYWORD || i == ENUM_KEYWORD) {
|
||||
else if (ElementType.CLASS_KEYWORD_BIT_SET.contains(i)) {
|
||||
return getChildRole(child, ChildRole.CLASS_OR_INTERFACE_KEYWORD);
|
||||
}
|
||||
else if (i == IDENTIFIER) {
|
||||
@@ -403,5 +403,4 @@ public class ClassElement extends CompositeElement implements Constants {
|
||||
protected boolean isVisibilitySupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-35
@@ -17,6 +17,7 @@ package com.intellij.psi.impl.source.tree.java;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.DebugUtil;
|
||||
@@ -27,19 +28,15 @@ import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.tree.ChildRoleBase;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements PsiMethodCallExpression {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl");
|
||||
@NonNls private static final String GET_CLASS_METHOD = "getClass";
|
||||
|
||||
public PsiMethodCallExpressionImpl() {
|
||||
super(JavaElementType.METHOD_CALL_EXPRESSION);
|
||||
@@ -174,39 +171,19 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements
|
||||
private static PsiType getResultType(PsiExpression call, PsiReferenceExpression methodExpression, JavaResolveResult result) {
|
||||
final PsiMethod method = (PsiMethod)result.getElement();
|
||||
if (method == null) return null;
|
||||
PsiManager manager = call.getManager();
|
||||
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(call);
|
||||
boolean is15OrHigher = languageLevel.compareTo(LanguageLevel.JDK_1_5) >= 0;
|
||||
//JLS3 15.8.2
|
||||
if (is15OrHigher &&
|
||||
GET_CLASS_METHOD.equals(method.getName()) &&
|
||||
CommonClassNames.JAVA_LANG_OBJECT.equals(method.getContainingClass().getQualifiedName())) {
|
||||
PsiExpression qualifier = methodExpression.getQualifierExpression();
|
||||
PsiType qualifierType = null;
|
||||
if (qualifier != null) {
|
||||
qualifierType = TypeConversionUtil.erasure(qualifier.getType());
|
||||
}
|
||||
else {
|
||||
ASTNode parent = call.getNode().getTreeParent();
|
||||
while (parent != null && parent.getElementType() != JavaElementType.CLASS) parent = parent.getTreeParent();
|
||||
if (parent != null) {
|
||||
qualifierType = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType((PsiClass)parent.getPsi());
|
||||
}
|
||||
}
|
||||
if (qualifierType != null) {
|
||||
PsiClass javaLangClass = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Class", call.getResolveScope());
|
||||
if (javaLangClass != null && javaLangClass.getTypeParameters().length == 1) {
|
||||
Map<PsiTypeParameter, PsiType> map = new HashMap<PsiTypeParameter, PsiType>();
|
||||
map.put(javaLangClass.getTypeParameters()[0], PsiWildcardType.createExtends(manager, qualifierType));
|
||||
PsiSubstitutor substitutor = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createSubstitutor(map);
|
||||
final PsiClassType classType = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory()
|
||||
.createType(javaLangClass, substitutor, languageLevel);
|
||||
final PsiElement parent = call.getParent();
|
||||
return parent instanceof PsiReferenceExpression && parent.getParent() instanceof PsiMethodCallExpression
|
||||
? PsiUtil.captureToplevelWildcards(classType, methodExpression) : classType;
|
||||
}
|
||||
}
|
||||
final PsiType getClassReturnType = PsiTypesUtil.patchMethodGetClassReturnType(call, methodExpression, method,
|
||||
new Condition<IElementType>() {
|
||||
@Override
|
||||
public boolean value(IElementType type) {
|
||||
return type != JavaElementType.CLASS;
|
||||
}
|
||||
}, languageLevel);
|
||||
|
||||
if (getClassReturnType != null) {
|
||||
return getClassReturnType;
|
||||
}
|
||||
|
||||
PsiType ret = method.getReturnType();
|
||||
|
||||
+3
-9
@@ -292,15 +292,9 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
if (containingClass.getConstructors().length == 0 &&
|
||||
!containingClass.isEnum() &&
|
||||
!containingClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
boolean hasReceiver = false;
|
||||
final PsiType[] parameterTypes = signature.getParameterTypes();
|
||||
|
||||
if (parameterTypes.length == 1 && PsiMethodReferenceUtil.isReceiverType(parameterTypes[0], containingClass, substitutor)) {
|
||||
hasReceiver = true;
|
||||
}
|
||||
final boolean innerClassOuterClassReference = containingClass.getContainingClass() != null && !containingClass.hasModifierProperty(PsiModifier.STATIC);
|
||||
ClassCandidateInfo candidateInfo = null;
|
||||
if ((containingClass.getContainingClass() == null || !isLocatedInStaticContext(containingClass)) && parameterTypes.length == 0 || hasReceiver && innerClassOuterClassReference) {
|
||||
if ((containingClass.getContainingClass() == null || !isLocatedInStaticContext(containingClass)) && signature.getParameterTypes().length == 0 ||
|
||||
PsiMethodReferenceUtil.onArrayType(containingClass, signature)) {
|
||||
candidateInfo = new ClassCandidateInfo(containingClass, substitutor);
|
||||
}
|
||||
return candidateInfo == null ? JavaResolveResult.EMPTY_ARRAY : new JavaResolveResult[]{candidateInfo};
|
||||
@@ -427,7 +421,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
final boolean staticOrValidConstructorRef = psiMethod.hasModifierProperty(PsiModifier.STATIC) || validConstructorRef;
|
||||
|
||||
if ((parameterTypes.length == signatureParameterTypes2.length || varArgs) &&
|
||||
(!myBeginsWithReferenceType || staticOrValidConstructorRef || (psiMethod.isConstructor() && conflict.isStaticsScopeCorrect()))) {
|
||||
(!(myBeginsWithReferenceType ^ staticOrValidConstructorRef) || (psiMethod.isConstructor() && conflict.isStaticsScopeCorrect()))) {
|
||||
boolean correct = true;
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
final PsiType type1 = subst.substitute(GenericsUtil.eliminateWildcards(parameterTypes[i]));
|
||||
|
||||
+2
-3
@@ -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.
|
||||
@@ -18,7 +18,6 @@ package com.intellij.psi.impl.source.tree.java;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
|
||||
import com.intellij.psi.impl.source.tree.*;
|
||||
import com.intellij.psi.tree.ChildRoleBase;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
@@ -39,7 +38,7 @@ public class PsiPackageStatementImpl extends CompositePsiElement implements PsiP
|
||||
@Override
|
||||
public String getPackageName() {
|
||||
PsiJavaCodeReferenceElement ref = getPackageReference();
|
||||
return ref == null ? null : SourceUtil.getTextSkipWhiteSpaceAndComments(SourceTreeToPsiMap.psiElementToTree(ref));
|
||||
return ref == null ? null : SourceUtil.getReferenceText(ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -730,7 +730,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
private String getCachedTextSkipWhiteSpaceAndComments() {
|
||||
String whiteSpaceAndComments = myCachedTextSkipWhiteSpaceAndComments;
|
||||
if (whiteSpaceAndComments == null) {
|
||||
myCachedTextSkipWhiteSpaceAndComments = whiteSpaceAndComments = SourceUtil.getTextSkipWhiteSpaceAndComments(this);
|
||||
myCachedTextSkipWhiteSpaceAndComments = whiteSpaceAndComments = SourceUtil.getReferenceText(this);
|
||||
}
|
||||
return whiteSpaceAndComments;
|
||||
}
|
||||
|
||||
+2
-2
@@ -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.
|
||||
@@ -38,7 +38,7 @@ public class PsiReferenceParameterListImpl extends CompositePsiElement implement
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiTypeElement[] getTypeParameterElements() {
|
||||
return getChildrenAsPsiElements(ElementType.TYPES_BIT_SET, PsiTypeElement.ARRAY_FACTORY);
|
||||
return getChildrenAsPsiElements(JavaElementType.TYPE, PsiTypeElement.ARRAY_FACTORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+14
-11
@@ -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.
|
||||
@@ -28,8 +28,6 @@ import com.intellij.psi.impl.java.stubs.PsiTypeParameterStub;
|
||||
import com.intellij.psi.impl.light.LightEmptyImplementsList;
|
||||
import com.intellij.psi.impl.meta.MetaRegistry;
|
||||
import com.intellij.psi.impl.source.JavaStubPsiElement;
|
||||
import com.intellij.psi.impl.source.tree.ChildRole;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.meta.PsiMetaData;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
@@ -44,7 +42,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author dsl
|
||||
* @author dsl
|
||||
*/
|
||||
public class PsiTypeParameterImpl extends JavaStubPsiElement<PsiTypeParameterStub> implements PsiTypeParameter {
|
||||
private final LightEmptyImplementsList myLightEmptyImplementsList = new LightEmptyImplementsList(null) {
|
||||
@@ -169,7 +167,7 @@ public class PsiTypeParameterImpl extends JavaStubPsiElement<PsiTypeParameterStu
|
||||
return PsiTreeUtil.getParentOfType(this, PsiTypeParameterListOwner.class);
|
||||
}
|
||||
|
||||
return (PsiTypeParameterListOwner) parentParent;
|
||||
return (PsiTypeParameterListOwner)parentParent;
|
||||
}
|
||||
|
||||
|
||||
@@ -183,9 +181,10 @@ public class PsiTypeParameterImpl extends JavaStubPsiElement<PsiTypeParameterStu
|
||||
|
||||
int ret = 0;
|
||||
PsiElement element = getPrevSibling();
|
||||
while(element != null){
|
||||
if(element instanceof PsiTypeParameter)
|
||||
while (element != null) {
|
||||
if (element instanceof PsiTypeParameter) {
|
||||
ret++;
|
||||
}
|
||||
element = element.getPrevSibling();
|
||||
}
|
||||
return ret;
|
||||
@@ -194,11 +193,14 @@ public class PsiTypeParameterImpl extends JavaStubPsiElement<PsiTypeParameterStu
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiIdentifier getNameIdentifier() {
|
||||
return (PsiIdentifier) calcTreeElement().findChildByRole(ChildRole.NAME);
|
||||
return PsiTreeUtil.getRequiredChildOfType(this, PsiIdentifier.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place){
|
||||
public boolean processDeclarations(@NotNull PsiScopeProcessor processor,
|
||||
@NotNull ResolveState state,
|
||||
PsiElement lastParent,
|
||||
@NotNull PsiElement place) {
|
||||
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, false);
|
||||
}
|
||||
|
||||
@@ -361,7 +363,7 @@ public class PsiTypeParameterImpl extends JavaStubPsiElement<PsiTypeParameterStu
|
||||
return "PsiTypeParameter:" + getName();
|
||||
}
|
||||
|
||||
public PsiMetaData getMetaData(){
|
||||
public PsiMetaData getMetaData() {
|
||||
return MetaRegistry.getMeta(this);
|
||||
}
|
||||
|
||||
@@ -384,7 +386,7 @@ public class PsiTypeParameterImpl extends JavaStubPsiElement<PsiTypeParameterStu
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiAnnotation[] getAnnotations() {
|
||||
return getStubOrPsiChildren(ElementType.ANNOTATIONS, PsiAnnotation.ARRAY_FACTORY);
|
||||
return getStubOrPsiChildren(JavaStubElementTypes.ANNOTATION, PsiAnnotation.ARRAY_FACTORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -397,6 +399,7 @@ public class PsiTypeParameterImpl extends JavaStubPsiElement<PsiTypeParameterStu
|
||||
public PsiAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiAnnotation[] getApplicableAnnotations() {
|
||||
|
||||
+17
-12
@@ -67,7 +67,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
checkSameSignatures(conflicts);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkAccessLevels(conflicts);
|
||||
checkAccessStaticLevels(conflicts, true);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkParametersNumber(conflicts, myActualParameterTypes.length, false);
|
||||
@@ -89,6 +89,9 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
checkPrimitiveVarargs(conflicts, myActualParameterTypes.length);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkAccessStaticLevels(conflicts, false);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
THashSet<CandidateInfo> uniques = new THashSet<CandidateInfo>(conflicts);
|
||||
if (uniques.size() == 1) return uniques.iterator().next();
|
||||
return null;
|
||||
@@ -123,12 +126,9 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
}
|
||||
}
|
||||
}
|
||||
LambdaUtil.checkMoreSpecificReturnType(conflicts, i);
|
||||
}
|
||||
else if (parameterType instanceof PsiMethodReferenceType) {
|
||||
LambdaUtil.checkMoreSpecificReturnType(conflicts, i);
|
||||
}
|
||||
}
|
||||
LambdaUtil.checkMoreSpecificReturnType(conflicts, myActualParameterTypes);
|
||||
}
|
||||
|
||||
public void checkSpecifics(List<CandidateInfo> conflicts, @MethodCandidateInfo.ApplicabilityLevelConstant int applicabilityLevel) {
|
||||
@@ -158,7 +158,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkAccessLevels(List<CandidateInfo> conflicts) {
|
||||
private static void checkAccessStaticLevels(List<CandidateInfo> conflicts, boolean checkAccessible) {
|
||||
int conflictsCount = conflicts.size();
|
||||
|
||||
int maxCheckLevel = -1;
|
||||
@@ -166,7 +166,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
int index = 0;
|
||||
for (final CandidateInfo conflict : conflicts) {
|
||||
final MethodCandidateInfo method = (MethodCandidateInfo)conflict;
|
||||
final int level = getCheckLevel(method);
|
||||
final int level = checkAccessible ? getCheckAccessLevel(method) : getCheckStaticLevel(method);
|
||||
checkLevels[index++] = level;
|
||||
maxCheckLevel = Math.max(maxCheckLevel, level);
|
||||
}
|
||||
@@ -379,11 +379,14 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return level;
|
||||
}
|
||||
|
||||
private static int getCheckLevel(MethodCandidateInfo method){
|
||||
boolean visible = method.isAccessible();// && !method.myStaticProblem;
|
||||
private static int getCheckAccessLevel(MethodCandidateInfo method){
|
||||
boolean visible = method.isAccessible();
|
||||
return visible ? 1 : 0;
|
||||
}
|
||||
|
||||
private static int getCheckStaticLevel(MethodCandidateInfo method){
|
||||
boolean available = method.isStaticsScopeCorrect();
|
||||
return (visible ? 1 : 0) << 2 |
|
||||
(available ? 1 : 0) << 1 |
|
||||
return (available ? 1 : 0) << 1 |
|
||||
(method.getCurrentFileResolveScope() instanceof PsiImportStaticStatement ? 0 : 1);
|
||||
}
|
||||
|
||||
@@ -550,7 +553,9 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
}
|
||||
if (isMoreSpecific == null) {
|
||||
if (!JavaVersionService.getInstance().isAtLeast(myArgumentsList, JavaSdkVersion.JDK_1_7) ||
|
||||
!MethodSignatureUtil.areParametersErasureEqual(method1, method2)) {
|
||||
!MethodSignatureUtil.areParametersErasureEqual(method1, method2) ||
|
||||
InheritanceUtil.isInheritorOrSelf(class1, class2, true) ||
|
||||
InheritanceUtil.isInheritorOrSelf(class2, class1, true)) {
|
||||
if (typeParameters1.length < typeParameters2.length) return Specifics.FIRST;
|
||||
if (typeParameters1.length > typeParameters2.length) return Specifics.SECOND;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class Foo {
|
||||
{
|
||||
try<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class Foo {
|
||||
{
|
||||
try
|
||||
{
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class Foo {
|
||||
{
|
||||
do<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class Foo {
|
||||
{
|
||||
do {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
public class Foo {
|
||||
|
||||
Zoo foo() {
|
||||
return r<caret>
|
||||
}
|
||||
|
||||
void rMethod() {}
|
||||
}
|
||||
|
||||
enum Zoo {
|
||||
LEFT, RIGHT
|
||||
}
|
||||
+1
-1
@@ -44,6 +44,6 @@ class UnsupportedFeatures {
|
||||
}
|
||||
|
||||
interface I {
|
||||
<error descr="Extension methods are not supported at this language level">void m() default { }</error>
|
||||
<error descr="Extension methods are not supported at this language level">default void m() { }</error>
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class Foo {
|
||||
public void foo() {}
|
||||
|
||||
public static void foo(String... s){}
|
||||
}
|
||||
|
||||
class A {
|
||||
{
|
||||
Foo.<error descr="Non-static method 'foo()' cannot be referenced from a static context">foo</error>();
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package pck;
|
||||
|
||||
class A {
|
||||
public void bar(I a, Class<Long> any) {
|
||||
System.out.println(a.with(any));
|
||||
}
|
||||
|
||||
interface I {
|
||||
<error descr="'with(Class<T>)' clashes with 'with(Class<Long>)'; both methods have same erasure"><T> T with(Class<T> aClass)</error>;
|
||||
long with(Class<Long> aClass);
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class Test {
|
||||
interface F<T extends Throwable> {
|
||||
void _(T t) throws T;
|
||||
}
|
||||
<K extends Throwable> void foo(F<K> f) throws K { }
|
||||
|
||||
{
|
||||
foo(<error descr="Cyclic inference">(t)->{}</error>);
|
||||
<error descr="Unhandled exception: java.lang.ClassNotFoundException">foo((ClassNotFoundException t)->{});</error>
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user