From bc4b2d79862866928d8332129837b6f4463d08ce Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Wed, 12 Jun 2013 12:38:29 -0700 Subject: [PATCH 01/11] IDEA-112878 Groovy code completion doesn't obey 'before parentheses -> method parentheses' settings. --- .../lang/completion/GroovyInsertHandler.java | 15 ++++--- .../completion/GroovyCompletionTest.groovy | 42 ++++++++++++++----- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyInsertHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyInsertHandler.java index 08c248897acc..1711e1e587bf 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyInsertHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyInsertHandler.java @@ -21,6 +21,7 @@ import com.intellij.codeInsight.TailType; import com.intellij.codeInsight.completion.InsertHandler; import com.intellij.codeInsight.completion.InsertionContext; import com.intellij.codeInsight.completion.util.MethodParenthesesHandler; +import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler; import com.intellij.codeInsight.lookup.Lookup; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.editor.CaretModel; @@ -28,6 +29,7 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NonNls; @@ -129,12 +131,13 @@ public class GroovyInsertHandler implements InsertHandler { return; } - new MethodParenthesesHandler(method, true) { - @Override - protected boolean placeCaretInsideParentheses(InsertionContext context, LookupElement item) { - return method.isConstructor() || super.placeCaretInsideParentheses(context, item); - } - }.handleInsert(context, item); + + CommonCodeStyleSettings settings = context.getCodeStyleSettings(); + ParenthesesInsertHandler.getInstance(MethodParenthesesHandler.hasParams(item, context.getElements(), true, method), + settings.SPACE_BEFORE_METHOD_CALL_PARENTHESES, + settings.SPACE_WITHIN_METHOD_CALL_PARENTHESES, + true, true).handleInsert(context, item); + AutoPopupController.getInstance(context.getProject()).autoPopupParameterInfo(editor, method); return; } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index 8678dcb924f1..bb963968588c 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -120,6 +120,7 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase { } public void testInstanceofHelpsDetermineTypeInBinaryAnd() { doBasicTest() } + public void testInstanceofHelpsDetermineTypeInBinaryOr() { doBasicTest() } public void testNotInstanceofDoesntHelpDetermineType() { @@ -210,6 +211,7 @@ class Foo { public void testWhileInstanceof() { doBasicTest() } public void testCompletionInParameterListInClosableBlock() { doBasicTest(); } + public void testCompletionInParameterListInClosableBlock3() { doBasicTest(); } public void testCompletionInParameterListInClosableBlock2() { @@ -261,8 +263,9 @@ class Foo { assert presentation.typeText == 'Integer' } - public void testIntCompletionInPlusMethod() {doBasicTest();} - public void testIntCompletionInGenericParameter() {doBasicTest();} + public void testIntCompletionInPlusMethod() { doBasicTest(); } + + public void testIntCompletionInGenericParameter() { doBasicTest(); } public void testWhenSiblingIsStaticallyImported_Method() { myFixture.addFileToProject "foo/Foo.groovy", """package foo @@ -706,7 +709,7 @@ form""" myFixture.checkResult """import static java.lang.String.format format()""" } - + public void testImportAsterisk() { myFixture.configureByText "a.groovy", "import java.lang." myFixture.completeBasic() @@ -826,7 +829,6 @@ class A { print myVar } }""" - } public void testParenthesesInMethodCompletion() { @@ -967,12 +969,13 @@ class Fopppp { myFixture.configureByText "a.groovy", text final LookupElement[] completion = myFixture.completeBasic() - return completion.find {println it.lookupString;itemToCheck == it.lookupString} + return completion.find { println it.lookupString; itemToCheck == it.lookupString } } public void testWordCompletionInLiterals() { checkSingleItemCompletion('def foo = "fo"', 'def foo = "foo"') } + public void testWordCompletionInLiterals2() { checkSingleItemCompletion(''' println "abcd" @@ -1028,7 +1031,6 @@ def conti = 4 while(true) { if (tst) cont }""") - } public void testPreferParametersToClasses() { @@ -1079,7 +1081,7 @@ class X { assertFalse(myFixture.lookupElementStrings.contains('Foo')) } - public void testClassNameBeforeParentheses(){ + public void testClassNameBeforeParentheses() { doBasicTest() } @@ -1164,7 +1166,7 @@ public class KeyVO { myFixture.addClass("package bar; public class Util { public static void bar() {} }") myFixture.configureByText 'a.groovy', 'Util.' myFixture.completeBasic() - assertOrderedEquals myFixture.lookupElementStrings[0..1] , ['Util.bar', 'Util.foo'] + assertOrderedEquals myFixture.lookupElementStrings[0..1], ['Util.bar', 'Util.foo'] def presentation = LookupElementPresentation.renderElement(myFixture.lookupElements[0]) assertEquals 'Util.bar', presentation.itemText @@ -1439,7 +1441,7 @@ import java.lang.annotation.Target; configure('@T @interface Foo {}') myFixture.completeBasic() - myFixture.assertPreferredCompletionItems 0, 'TMetaAnno', 'Target', 'TreeSelectionMode', 'TLocalAnno' + myFixture.assertPreferredCompletionItems 0, 'TMetaAnno', 'Target', 'TreeSelectionMode', 'TLocalAnno' } void testDiamondCompletion1() { @@ -1750,11 +1752,11 @@ class Inheritor extends Base { } """) - doVariantableTest('Inheritor.fo','', CompletionType.BASIC, CompletionResult.equal, 'foo', 'forName', 'forName') + doVariantableTest('Inheritor.fo', '', CompletionType.BASIC, CompletionResult.equal, 'foo', 'forName', 'forName') } void testBinding1() { - doCompletionTest('''\ + doCompletionTest('''\ aaa = 5 print aa ''', '''\ @@ -1854,5 +1856,23 @@ class Autocompletion { ''', '\t', CompletionType.BASIC) } + void testSpaceBeforeMethodCallParentheses() { + def settings = CodeStyleSettingsManager.getSettings(myFixture.project).getCommonSettings(GroovyFileType.GROOVY_LANGUAGE) + boolean old = settings.SPACE_BEFORE_METHOD_CALL_PARENTHESES + try { + settings.SPACE_BEFORE_METHOD_CALL_PARENTHESES = true + doCompletionTest('''\ +def foooo() {} +fooo +''', '''\ +def foooo() {} +foooo () +''', '', CompletionType.BASIC) + } + finally { + settings.SPACE_BEFORE_METHOD_CALL_PARENTHESES = old + + } + } } \ No newline at end of file From 8bc5fbfc6492509cd546d14e668ec89e8f197fc5 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Wed, 12 Jun 2013 12:38:29 -0700 Subject: [PATCH 02/11] IDEA-111780 Extract method from static closure should create static method --- .../method/ExtractMethodInfoHelper.java | 6 +-- .../extract/method/ExtractMethodTest.groovy | 41 +++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/method/ExtractMethodInfoHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/method/ExtractMethodInfoHelper.java index 52a913ce125e..0149acf92ca7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/method/ExtractMethodInfoHelper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/method/ExtractMethodInfoHelper.java @@ -21,7 +21,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiModifier; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember; import org.jetbrains.plugins.groovy.refactoring.extract.ExtractInfoHelperBase; import org.jetbrains.plugins.groovy.refactoring.extract.InitialInfo; @@ -88,8 +88,8 @@ public class ExtractMethodInfoHelper extends ExtractInfoHelperBase { private static boolean canBeStatic(PsiElement statement) { PsiElement parent = statement.getParent(); while (parent != null && !(parent instanceof PsiFile)) { - if (parent instanceof GrMethod) { - return ((GrMethod) parent).hasModifierProperty(PsiModifier.STATIC); + if (parent instanceof GrMember) { + return ((GrMember) parent).hasModifierProperty(PsiModifier.STATIC); } parent = parent.getParent(); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/extract/method/ExtractMethodTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/extract/method/ExtractMethodTest.groovy index cf167e024754..d17fea8cae5d 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/extract/method/ExtractMethodTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/extract/method/ExtractMethodTest.groovy @@ -198,4 +198,45 @@ private int testMethod() { } ''') } + + void testExtractMethodFromStaticFieldClosureInitializer() { + doTest('''\ +class Foo { + static constraints = { + bar validator: { val, obj -> + println "validating ${obj}.$val" + } + } +} +''', '''\ +class Foo { + static constraints = { + bar validator: { val, obj -> + testMethod(obj, val) + } + } + + private static testMethod(obj, val) { + println "validating ${obj}.$val" + } +} +''') + } + + void testExtractMethodFromStaticFieldInitializer() { + doTest('''\ +class Foo { + static constraints = 2 +} +''', '''\ +class Foo { + static constraints = testMethod() + + private static int testMethod() { + return 2 + } +} +''') + } + } \ No newline at end of file From 28a1e72c44d7428c6055d78f8ebdb0b3c0e79b0d Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 7 Sep 2013 16:38:10 +0200 Subject: [PATCH 03/11] cleanup --- ...StaticFieldFromInstanceInspectionBase.java | 35 +++++++------------ ...SafeStaticFieldFromInstanceInspection.java | 16 +++------ 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase.java index d9d8f483a7aa..efe3776b29c9 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase.java @@ -29,11 +29,11 @@ import org.jetbrains.annotations.NotNull; import java.util.List; public class AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase extends BaseInspection { + public AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase() { - if (nonThreadSafeTypes.length() != 0) { + if (!nonThreadSafeTypes.isEmpty()) { nonThreadSafeClasses.clear(); - final List strings = - StringUtil.split(nonThreadSafeTypes, ","); + final List strings = StringUtil.split(nonThreadSafeTypes, ","); for (String string : strings) { nonThreadSafeClasses.add(string); } @@ -43,9 +43,8 @@ public class AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase extends @SuppressWarnings("PublicField") public final ExternalizableStringSet nonThreadSafeClasses = - new ExternalizableStringSet( - "java.text.SimpleDateFormat", - "java.util.Calendar"); + new ExternalizableStringSet("java.text.SimpleDateFormat", "java.util.Calendar"); + @NonNls @SuppressWarnings({"PublicField"}) public String nonThreadSafeTypes = ""; @@ -60,16 +59,13 @@ public class AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase extends @Nls @NotNull public String getDisplayName() { - return InspectionGadgetsBundle.message( - "access.to.non.thread.safe.static.field.from.instance.display.name"); + return InspectionGadgetsBundle.message("access.to.non.thread.safe.static.field.from.instance.display.name"); } @Override @NotNull protected String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "access.to.non.thread.safe.static.field.from.instance.field.problem.descriptor", - infos[0]); + return InspectionGadgetsBundle.message("access.to.non.thread.safe.static.field.from.instance.field.problem.descriptor", infos[0]); } @Override @@ -77,28 +73,21 @@ public class AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase extends return new AccessToNonThreadSafeStaticFieldFromInstanceVisitor(); } - class AccessToNonThreadSafeStaticFieldFromInstanceVisitor - extends BaseInspectionVisitor { + class AccessToNonThreadSafeStaticFieldFromInstanceVisitor extends BaseInspectionVisitor { @Override - public void visitReferenceExpression( - PsiReferenceExpression expression) { + public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); final PsiModifierListOwner parent = - PsiTreeUtil.getParentOfType(expression, - PsiField.class, PsiMethod.class, - PsiClassInitializer.class); + PsiTreeUtil.getParentOfType(expression, PsiField.class, PsiMethod.class, PsiClassInitializer.class); if (parent == null) { return; } - if (parent instanceof PsiMethod || - parent instanceof PsiClassInitializer) { + if (parent instanceof PsiMethod || parent instanceof PsiClassInitializer) { if (parent.hasModifierProperty(PsiModifier.SYNCHRONIZED)) { return; } - final PsiSynchronizedStatement synchronizedStatement = - PsiTreeUtil.getParentOfType(expression, - PsiSynchronizedStatement.class); + final PsiSynchronizedStatement synchronizedStatement = PsiTreeUtil.getParentOfType(expression, PsiSynchronizedStatement.class); if (synchronizedStatement != null) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspection.java index 278bb940e30c..47350d969db4 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspection.java @@ -15,27 +15,21 @@ */ package com.siyeh.ig.threading; -import com.intellij.openapi.util.text.StringUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.ui.UiUtils; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.List; -public class AccessToNonThreadSafeStaticFieldFromInstanceInspection - extends AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase { +public class AccessToNonThreadSafeStaticFieldFromInstanceInspection extends AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase { - public AccessToNonThreadSafeStaticFieldFromInstanceInspection() { - } + public AccessToNonThreadSafeStaticFieldFromInstanceInspection() {} @Override @Nullable public JComponent createOptionsPanel() { - return UiUtils.createTreeClassChooserList(nonThreadSafeClasses, - InspectionGadgetsBundle.message( - "access.to.non.thread.safe.static.field.from.instance.option.title"), - InspectionGadgetsBundle.message( - "access.to.non.thread.safe.static.field.from.instance.class.chooser.title")); + return UiUtils.createTreeClassChooserList( + nonThreadSafeClasses, InspectionGadgetsBundle.message("access.to.non.thread.safe.static.field.from.instance.option.title"), + InspectionGadgetsBundle.message("access.to.non.thread.safe.static.field.from.instance.class.chooser.title")); } } \ No newline at end of file From 0b795bec0fad008bf07f6239d21fe63a51cc0ead Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 7 Sep 2013 21:24:57 +0200 Subject: [PATCH 04/11] IDEA-85224 (Inspection "non thread-safe static field access" gives false +ve for static initializers) --- .../src/com/siyeh/ig/psiutils/TypeUtils.java | 29 ++++++---- ...StaticFieldFromInstanceInspectionBase.java | 35 ++++++++++-- ...StaticFieldFromInstanceInspectionTest.java | 54 +++++++++++++++++++ 3 files changed, 104 insertions(+), 14 deletions(-) create mode 100644 plugins/InspectionGadgets/testsrc/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionTest.java diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TypeUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TypeUtils.java index 30acc98df96a..5bb992dbbc90 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TypeUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TypeUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,12 +23,9 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; - public class TypeUtils { - private TypeUtils() { - } + private TypeUtils() {} public static boolean typeEquals(@NonNls @NotNull String typeName, @Nullable PsiType targetType) { return targetType != null && targetType.equalsToText(typeName); @@ -57,6 +54,21 @@ public class TypeUtils { return typeEquals(CommonClassNames.JAVA_LANG_STRING, targetType); } + public static boolean isExpressionTypeAssignableWith(@NotNull PsiExpression expression, @NotNull Iterable rhsTypeTexts) { + final PsiType type = expression.getType(); + if (type == null) { + return false; + } + final PsiElementFactory factory = JavaPsiFacade.getInstance(expression.getProject()).getElementFactory(); + for (String rhsTypeText : rhsTypeTexts) { + final PsiClassType rhsType = factory.createTypeByFQClassName(rhsTypeText, expression.getResolveScope()); + if (type.isAssignableFrom(rhsType)) { + return true; + } + } + return false; + } + public static boolean expressionHasTypeOrSubtype(@Nullable PsiExpression expression, @NonNls @NotNull String typeName) { if (expression == null) { return false; @@ -98,7 +110,7 @@ public class TypeUtils { return null; } - public static boolean expressionHasTypeOrSubtype(@Nullable PsiExpression expression, @NonNls @NotNull Collection typeNames) { + public static boolean expressionHasTypeOrSubtype(@Nullable PsiExpression expression, @NonNls @NotNull Iterable typeNames) { if (expression == null) { return false; } @@ -148,9 +160,6 @@ public class TypeUtils { return false; } final PsiType type = expression.getType(); - if (type == null) { - return false; - } - return PsiType.FLOAT.equals(type) || PsiType.DOUBLE.equals(type); + return type != null && (PsiType.FLOAT.equals(type) || PsiType.DOUBLE.equals(type)); } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase.java index efe3776b29c9..b051e2e653a2 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase.java @@ -21,6 +21,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.psiutils.TypeUtils; import com.siyeh.ig.ui.ExternalizableStringSet; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; @@ -92,8 +93,12 @@ public class AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase extends return; } } - final PsiExpression qualifier = expression.getQualifierExpression(); - if (qualifier != null) { + if (parent instanceof PsiField || parent instanceof PsiClassInitializer) { + if (parent.hasModifierProperty(PsiModifier.STATIC)) { + return; + } + } + if (expression.getQualifierExpression() != null) { return; } final PsiType type = expression.getType(); @@ -102,8 +107,12 @@ public class AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase extends } final PsiClassType classType = (PsiClassType)type; final String className = classType.rawType().getCanonicalText(); + boolean deepCheck = false; if (!nonThreadSafeClasses.contains(className)) { - return; + if (!TypeUtils.isExpressionTypeAssignableWith(expression, nonThreadSafeClasses)) { + return; + } + deepCheck = true; } final PsiElement target = expression.resolve(); if (!(target instanceof PsiField)) { @@ -113,7 +122,25 @@ public class AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase extends if (!field.hasModifierProperty(PsiModifier.STATIC)) { return; } - registerError(expression, className); + if (deepCheck) { + final PsiExpression initializer = field.getInitializer(); + if (initializer == null) { + return; + } + final PsiType initializerType = initializer.getType(); + if (!(initializerType instanceof PsiClassType)) { + return; + } + final PsiClassType classType2 = (PsiClassType)initializerType; + final String className2 = classType2.rawType().getCanonicalText(); + if (!nonThreadSafeClasses.contains(className2)) { + return; + } + registerError(expression, className2); + } + else { + registerError(expression, className); + } } } } diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionTest.java new file mode 100644 index 000000000000..ae551ccb3ea0 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionTest.java @@ -0,0 +1,54 @@ +package com.siyeh.ig.threading; + +import com.intellij.codeInspection.LocalInspectionTool; +import com.siyeh.ig.LightInspectionTestCase; + +/** + * @author Bas Leijdekkers + */ +public class AccessToNonThreadSafeStaticFieldFromInstanceInspectionTest extends LightInspectionTestCase { + + @Override + protected String[] getEnvironmentClasses() { + return new String[]{ + "package java.text;" + + "import java.util.Date;" + + "public abstract class DateFormat {" + + " public String format(Date d) {}" + + "}", + "package java.text;" + + "public class SimpleDateFormat extends DateFormat {" + + " public SimpleDateFormat(String s) {}" + + "}" + }; + } + + public void testSimple() { + doTest("import java.util.Date;" + + "import java.text.DateFormat;" + + "import java.text.SimpleDateFormat;" + + "class C {" + + " private static final SimpleDateFormat df = new SimpleDateFormat(\"yyyy-MM-dd\");" + + " private String s = /*Access to non thread-safe static field 'df' of type 'java.text.SimpleDateFormat'*/df/**/.format(new Date());" + + "}"); + } + + public void testDeepCheck() { + doTest("import java.util.Date;" + + "import java.text.DateFormat;" + + "import java.text.SimpleDateFormat;" + + "class C {" + + " private static final DateFormat df = new SimpleDateFormat(\"yyyy-MM-dd\");" + + " private static final Date d = new Date();" + + " private static final String s1 = df.format(d);" + + " String m() {" + + " return /*Access to non thread-safe static field 'df' of type 'java.text.SimpleDateFormat'*/df/**/.format(d);" + + " }" + + "}"); + } + + @Override + protected LocalInspectionTool getInspection() { + return new AccessToNonThreadSafeStaticFieldFromInstanceInspection(); + } +} \ No newline at end of file From e7fa284f51c303b3dba2a26e7901338c61aff29e Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Sat, 7 Sep 2013 12:29:57 -0700 Subject: [PATCH 05/11] IDEA-113346 False negative in groovy withStream closure --- .../lang/psi/typeEnhancers/ClosureParameterEnhancer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java index d6854fdea9c8..cd65ac2f629f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java @@ -31,6 +31,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; import org.jetbrains.plugins.groovy.lang.psi.impl.GrRangeType; import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; @@ -227,7 +228,10 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer { } else if (GdkMethodUtil.WITH_STREAM.equals(methodName)) { final PsiMethod method = ((GrMethodCall)parent).resolveMethod(); - if (method != null) { + if (method instanceof GrGdkMethod) { + return qualifier.getType(); + } + else if (method != null) { final PsiParameter[] parameters = method.getParameterList().getParameters(); if (parameters.length > 0) { return parameters[0].getType(); From 72c972fc46a240ed21e07c515596a013f434153a Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Sat, 7 Sep 2013 20:12:04 -0700 Subject: [PATCH 06/11] auto inject RegExp lang to reg-exp operator argeuments --- .../psi/patterns/GroovyElementPattern.java | 22 ++++++++++++++----- .../groovy/src/resources/groovyInjections.xml | 4 ++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/patterns/GroovyElementPattern.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/patterns/GroovyElementPattern.java index 66e490ce2636..d2247de58111 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/patterns/GroovyElementPattern.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/patterns/GroovyElementPattern.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,14 +20,12 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; public class GroovyElementPattern> extends PsiJavaElementPattern { public GroovyElementPattern(final Class aClass) { @@ -90,6 +88,20 @@ public class GroovyElementPattern("regExpOperatorArg") { + @Override + public boolean accepts(@NotNull T t, ProcessingContext context) { + PsiElement parent = t.getParent(); + return parent instanceof GrUnaryExpression && ((GrUnaryExpression)parent).getOperationTokenType() == GroovyTokenTypes.mBNOT || + parent instanceof GrBinaryExpression && t == ((GrBinaryExpression)parent).getRightOperand() && ((GrBinaryExpression)parent).getOperationTokenType() == GroovyTokenTypes.mREGEX_FIND || + parent instanceof GrBinaryExpression && t == ((GrBinaryExpression)parent).getRightOperand() && ((GrBinaryExpression)parent).getOperationTokenType() == GroovyTokenTypes.mREGEX_MATCH; + } + }); + } + + + public static class Capture extends GroovyElementPattern> { public Capture(final Class aClass) { super(aClass); diff --git a/plugins/groovy/src/resources/groovyInjections.xml b/plugins/groovy/src/resources/groovyInjections.xml index 1953973bdeb1..dcb426aa135f 100644 --- a/plugins/groovy/src/resources/groovyInjections.xml +++ b/plugins/groovy/src/resources/groovyInjections.xml @@ -46,4 +46,8 @@ + + RegExp + + From 8941cf8fb5a92c0b0b6545ad7d404bad221b9537 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sun, 8 Sep 2013 12:29:27 +0200 Subject: [PATCH 07/11] IDEA-113298 (replace assertTrue with assertFalse removes message) --- .../ipp/junit/FlipAssertLiteralIntention.java | 9 ++--- .../junit/flip_assert_literal/Message.java | 9 +++++ .../flip_assert_literal/Message_after.java | 9 +++++ .../junit/FlipAssertLiteralIntentionTest.java | 36 +++++++++++++++++++ 4 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/junit/flip_assert_literal/Message.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/junit/flip_assert_literal/Message_after.java create mode 100644 plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/junit/FlipAssertLiteralIntentionTest.java diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/junit/FlipAssertLiteralIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/junit/FlipAssertLiteralIntention.java index 361197648abe..ac90d38e1dcf 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/junit/FlipAssertLiteralIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/junit/FlipAssertLiteralIntention.java @@ -78,12 +78,13 @@ public class FlipAssertLiteralIntention extends MutablyNamedIntention { } newCall.append(toMethodName).append('('); final PsiExpressionList argumentList = call.getArgumentList(); - final PsiExpression[] args = argumentList.getExpressions(); - if (args.length == 1) { - newCall.append(BoolUtils.getNegatedExpressionText(args[0])); + final PsiExpression[] arguments = argumentList.getExpressions(); + if (arguments.length == 1) { + newCall.append(BoolUtils.getNegatedExpressionText(arguments[0])); } else { - newCall.append(BoolUtils.getNegatedExpressionText(args[1])); + newCall.append(arguments[0].getText()).append(','); + newCall.append(BoolUtils.getNegatedExpressionText(arguments[1])); } newCall.append(')'); replaceExpression(newCall.toString(), call); diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/junit/flip_assert_literal/Message.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/junit/flip_assert_literal/Message.java new file mode 100644 index 000000000000..6cfd0b6d585e --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/junit/flip_assert_literal/Message.java @@ -0,0 +1,9 @@ +package com.siyeh.ipp.junit.flip_assert_literal; + +import org.junit.Assert; + +class Messsage { + void test(boolean b) { + Assert.assertTrue("message", !b); + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/junit/flip_assert_literal/Message_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/junit/flip_assert_literal/Message_after.java new file mode 100644 index 000000000000..410867880ac3 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/junit/flip_assert_literal/Message_after.java @@ -0,0 +1,9 @@ +package com.siyeh.ipp.junit.flip_assert_literal; + +import org.junit.Assert; + +class Messsage { + void test(boolean b) { + Assert.assertFalse("message", b); + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/junit/FlipAssertLiteralIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/junit/FlipAssertLiteralIntentionTest.java new file mode 100644 index 000000000000..edf39058bc90 --- /dev/null +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/junit/FlipAssertLiteralIntentionTest.java @@ -0,0 +1,36 @@ +/** + * (c) 2013 Desert Island BV + * created: 08 09 2013 + */ +package com.siyeh.ipp.junit; + +import com.siyeh.IntentionPowerPackBundle; +import com.siyeh.ipp.IPPTestCase; + +/** + * @see FlipAssertLiteralIntention + * @author Bas Leijdekkers + */ +public class FlipAssertLiteralIntentionTest extends IPPTestCase { + + public void testMessage() { doTest(); } + + @Override + protected void setUp() throws Exception { + super.setUp(); + myFixture.addClass("package org.junit;" + + "class Assert {" + + " public static void assertTrue(java.lang.String message, boolean condition) {}" + + "}"); + } + + @Override + protected String getRelativePath() { + return "junit/flip_assert_literal"; + } + + @Override + protected String getIntentionName() { + return IntentionPowerPackBundle.message("flip.assert.literal.intention.name", "assertTrue", "assertFalse"); + } +} From 2d25b3b63581adcbade62e5c900c851832782fed Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sun, 8 Sep 2013 15:07:50 +0200 Subject: [PATCH 08/11] DRY --- .../MethodMayBeStaticInspection.java | 55 +------------------ 1 file changed, 3 insertions(+), 52 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/MethodMayBeStaticInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/MethodMayBeStaticInspection.java index 57ac5aebf88d..51c7c511d6c8 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/MethodMayBeStaticInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/MethodMayBeStaticInspection.java @@ -29,7 +29,7 @@ import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.ChangeModifierFix; import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.MethodUtils; -import org.jetbrains.annotations.NonNls; +import com.siyeh.ig.psiutils.SerializationUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -168,57 +168,8 @@ public class MethodMayBeStaticInspection extends BaseInspection { } private boolean isExcluded(PsiMethod method) { - @NonNls final String name = method.getName(); - if ("writeObject".equals(name)) { - if (!method.hasModifierProperty(PsiModifier.PRIVATE)) { - return false; - } - if (!MethodUtils.hasInThrows(method, "java.io.IOException")) { - return false; - } - final PsiType returnType = method.getReturnType(); - if (!PsiType.VOID.equals(returnType)) { - return false; - } - final PsiParameterList parameterList = method.getParameterList(); - if (parameterList.getParametersCount() != 1) { - return false; - } - final PsiParameter parameter = parameterList.getParameters()[0]; - final PsiType type = parameter.getType(); - return type.equalsToText("java.io.ObjectOutputStream"); - } - if ("readObject".equals(name)) { - if (!method.hasModifierProperty(PsiModifier.PRIVATE)) { - return false; - } - if (!MethodUtils.hasInThrows(method, "java.io.IOException", "java.lang.ClassNotFoundException")) { - return false; - } - final PsiType returnType = method.getReturnType(); - if (!PsiType.VOID.equals(returnType)) { - return false; - } - final PsiParameterList parameterList = method.getParameterList(); - if (parameterList.getParametersCount() != 1) { - return false; - } - final PsiParameter parameter = parameterList.getParameters()[0]; - final PsiType type = parameter.getType(); - return type.equalsToText("java.io.ObjectInputStream"); - } - if ("writeReplace".equals(name) || "readResolve".equals(name)) { - if (!MethodUtils.hasInThrows(method, "java.io.ObjectStreamException")) { - return false; - } - final PsiType returnType = method.getReturnType(); - if (returnType == null || !returnType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) { - return false; - } - final PsiParameterList parameterList = method.getParameterList(); - return parameterList.getParametersCount() == 0; - } - return false; + return SerializationUtils.isWriteObject(method) || SerializationUtils.isReadObject(method) || + SerializationUtils.isWriteReplace(method) || SerializationUtils.isReadResolve(method); } } } From 12e32a8890e68b415f8ba3e6c9499477c51a48c9 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sun, 8 Sep 2013 15:09:18 +0200 Subject: [PATCH 09/11] IDEA-96419 ("Externalizable class without public no-arg constructor" inspection options) --- ...eWithoutPublicNoArgConstructorInspection.java | 6 +++++- ...ernalizableWithoutPublicNoArgConstructor.java | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/ExternalizableWithoutPublicNoArgConstructorInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/ExternalizableWithoutPublicNoArgConstructorInspection.java index 9aa075377bf3..d4b611a96e3b 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/ExternalizableWithoutPublicNoArgConstructorInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/ExternalizableWithoutPublicNoArgConstructorInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.DelegatingFix; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.psiutils.ClassUtils; +import com.siyeh.ig.psiutils.SerializationUtils; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -134,6 +135,9 @@ public class ExternalizableWithoutPublicNoArgConstructorInspection extends BaseI return; } } + if (SerializationUtils.hasWriteReplace(aClass)) { + return; + } registerClassError(aClass, aClass, constructor); } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/serialization/externalizable_without_public_no_arg_constructor/ExternalizableWithoutPublicNoArgConstructor.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/serialization/externalizable_without_public_no_arg_constructor/ExternalizableWithoutPublicNoArgConstructor.java index 0be95608c044..ddeaa57266df 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/serialization/externalizable_without_public_no_arg_constructor/ExternalizableWithoutPublicNoArgConstructor.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/serialization/externalizable_without_public_no_arg_constructor/ExternalizableWithoutPublicNoArgConstructor.java @@ -57,4 +57,20 @@ class AnonymousTest { System.out.println("o = " + o); } } +public class ExternalizableWithoutPublicNoArgConstructor implements Externalizable { + + protected ExternalizableWithoutPublicNoArgConstructor() {} + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + } + + public Object writeReplace() throws ObjectStreamException { + return null; + } +} From 482c517f0da001fb64b1cc64b216ea8d90e9c110 Mon Sep 17 00:00:00 2001 From: Fedor Korotkov Date: Sun, 8 Sep 2013 20:53:25 +0400 Subject: [PATCH 10/11] WEB-8397 Incorrect "element is not allowed here" inspection script tag contains only character data according http://www.w3.org/TR/html-markup/script.html --- xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java | 7 ------- xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java b/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java index e09bc2264fdc..aed3c551a2f6 100644 --- a/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java +++ b/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java @@ -154,13 +154,6 @@ abstract class BaseHtmlLexer extends DelegateLexer { } } } - - @Nullable - protected Language getScriptLanguage() { - Collection instancesByMimeType = Language.findInstancesByMimeType(scriptType != null ? scriptType.trim() : null); - return instancesByMimeType.isEmpty() ? null : instancesByMimeType.iterator().next(); - } - @Nullable protected IElementType getCurrentScriptElementType() { HtmlScriptContentProvider scriptContentProvider = findScriptContentProvider(scriptType); diff --git a/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java b/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java index 98858a387dff..dc0e4d3f6cfd 100644 --- a/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java +++ b/xml/xml-psi-impl/src/com/intellij/lexer/HtmlLexer.java @@ -16,9 +16,7 @@ package com.intellij.lexer; import com.intellij.lang.HtmlInlineScriptTokenTypesProvider; -import com.intellij.lang.Language; import com.intellij.lang.LanguageHtmlInlineScriptTokenTypesProvider; -import com.intellij.lang.LanguageUtil; import com.intellij.openapi.extensions.Extensions; import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; @@ -76,9 +74,7 @@ public class HtmlLexer extends BaseHtmlLexer { tokenType = ourInlineStyleElementType; } } else if (hasSeenScript()) { - Language scriptLanguage = getScriptLanguage(); - boolean canInject = scriptLanguage == null || LanguageUtil.isInjectableLanguage(scriptLanguage); - if (hasSeenTag() && isStartOfEmbeddmentTagContent(tokenType) && canInject) { + if (hasSeenTag() && isStartOfEmbeddmentTagContent(tokenType)) { myTokenEnd = skipToTheEndOfTheEmbeddment(); IElementType currentScriptElementType = getCurrentScriptElementType(); tokenType = currentScriptElementType == null ? XmlTokenType.XML_DATA_CHARACTERS : currentScriptElementType; From 134a7faa4f5d0f60f2a999337c85df5380c1f912 Mon Sep 17 00:00:00 2001 From: Fedor Korotkov Date: Sun, 8 Sep 2013 20:53:58 +0400 Subject: [PATCH 11/11] WEB-8731 HTML parser breaks with unquoted complex attributes --- .../src/com/intellij/lexer/_HtmlLexer.flex | 4 +- .../src/com/intellij/lexer/_HtmlLexer.java | 219 +++++++++--------- 2 files changed, 109 insertions(+), 114 deletions(-) diff --git a/xml/xml-psi-impl/src/com/intellij/lexer/_HtmlLexer.flex b/xml/xml-psi-impl/src/com/intellij/lexer/_HtmlLexer.flex index 8def2be62dfb..275c4c957d7e 100644 --- a/xml/xml-psi-impl/src/com/intellij/lexer/_HtmlLexer.flex +++ b/xml/xml-psi-impl/src/com/intellij/lexer/_HtmlLexer.flex @@ -25,7 +25,7 @@ import com.intellij.psi.xml.*; %class _HtmlLexer %public -%implements FlexLexer,ELHostLexer +%implements FlexLexer %function advance %type IElementType %eof{ return; @@ -124,7 +124,7 @@ CONDITIONAL_COMMENT_CONDITION=({ALPHA})({ALPHA}|{WHITE_SPACE_CHARS}|{DIGIT}|"."| return elTokenType2; } - ([^ \n\r\t\f'\"\>]|(\/[^\>]))* { yybegin(TAG_ATTRIBUTES); return XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; } + [^ \n\r\t\f'\"\>]([^ \n\r\t\f\>]|(\/[^\>]))* { yybegin(TAG_ATTRIBUTES); return XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; } "\"" { yybegin(ATTRIBUTE_VALUE_DQ); return XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER; } "'" { yybegin(ATTRIBUTE_VALUE_SQ); return XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER; } diff --git a/xml/xml-psi-impl/src/com/intellij/lexer/_HtmlLexer.java b/xml/xml-psi-impl/src/com/intellij/lexer/_HtmlLexer.java index e35b5b91c502..d1e78a6d366a 100644 --- a/xml/xml-psi-impl/src/com/intellij/lexer/_HtmlLexer.java +++ b/xml/xml-psi-impl/src/com/intellij/lexer/_HtmlLexer.java @@ -1,54 +1,50 @@ -/* - * Copyright 2000-2009 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. - */ - -/* The following code was generated by JFlex 1.4.1 on 01.06.09 13:59 */ +/* The following code was generated by JFlex 1.4.3 on 9/8/13 3:03 PM */ /* It's an automatically generated code. Do not modify it. */ package com.intellij.lexer; import com.intellij.psi.tree.IElementType; -import com.intellij.psi.xml.XmlTokenType; +import com.intellij.psi.*; +import com.intellij.psi.xml.*; /** * This class is a scanner generated by - * JFlex 1.4.1 - * on 01.06.09 13:59 from the specification file - * C:/Trunk/tools/lexer/_HtmlLexer.flex + * JFlex 1.4.3 + * on 9/8/13 3:03 PM from the specification file + * /Users/fedorkorotkov/workspaces/idea/community/xml/xml-psi-impl/src/com/intellij/lexer/_HtmlLexer.flex */ public class _HtmlLexer implements FlexLexer { /** initial size of the lookahead buffer */ private static final int ZZ_BUFFERSIZE = 16384; /** lexical states */ - public static final int PROCESSING_INSTRUCTION = 9; - public static final int C_COMMENT_END = 14; - public static final int END_TAG_NAME = 4; - public static final int START_TAG_NAME = 3; - public static final int ATTRIBUTE_VALUE_SQ = 8; - public static final int DOC_TYPE = 1; - public static final int ATTRIBUTE_VALUE_DQ = 7; + public static final int PROCESSING_INSTRUCTION = 18; + public static final int C_COMMENT_END = 28; + public static final int END_TAG_NAME = 8; + public static final int START_TAG_NAME = 6; + public static final int ATTRIBUTE_VALUE_SQ = 16; + public static final int DOC_TYPE = 2; + public static final int ATTRIBUTE_VALUE_DQ = 14; public static final int YYINITIAL = 0; - public static final int TAG_CHARACTERS = 12; - public static final int START_TAG_NAME2 = 10; - public static final int TAG_ATTRIBUTES = 5; - public static final int COMMENT = 2; - public static final int ATTRIBUTE_VALUE_START = 6; - public static final int C_COMMENT_START = 13; - public static final int END_TAG_NAME2 = 11; + public static final int TAG_CHARACTERS = 24; + public static final int START_TAG_NAME2 = 20; + public static final int TAG_ATTRIBUTES = 10; + public static final int COMMENT = 4; + public static final int ATTRIBUTE_VALUE_START = 12; + public static final int C_COMMENT_START = 26; + public static final int END_TAG_NAME2 = 22; + + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14 + }; /** * Translates characters to character classes @@ -129,15 +125,15 @@ public class _HtmlLexer implements FlexLexer { private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = - "\1\1\5\0\1\2\2\0\1\3\5\0\1\1\1\4"+ - "\5\1\1\5\1\6\4\5\1\7\1\5\4\10\1\11"+ - "\1\12\1\13\1\14\2\12\1\15\1\16\1\12\1\17"+ - "\1\2\1\20\1\21\2\2\1\22\1\23\4\22\1\3"+ - "\1\24\1\5\1\25\3\26\1\27\1\10\3\27\1\30"+ - "\1\31\1\32\1\0\1\33\1\34\15\0\1\34\1\35"+ - "\2\2\3\0\1\36\2\0\1\37\1\40\1\41\1\42"+ - "\11\0\1\43\1\44\1\0\1\45\1\2\1\45\1\46"+ - "\1\0\1\47\3\0\1\15\3\0\1\50\2\0\1\51"; + "\1\1\10\0\1\2\5\0\1\1\1\3\5\1\1\4"+ + "\1\5\4\4\1\6\1\4\4\7\1\10\1\11\1\12"+ + "\1\13\2\11\1\14\1\15\1\11\1\16\1\17\1\20"+ + "\1\21\2\17\1\22\1\23\4\22\1\2\1\24\1\4"+ + "\1\25\3\26\1\27\1\7\3\27\1\30\1\31\1\32"+ + "\1\0\1\33\1\34\15\0\1\34\1\35\2\17\3\0"+ + "\1\36\2\0\1\37\1\40\1\41\1\42\11\0\1\43"+ + "\1\44\1\0\1\45\1\17\1\45\1\46\1\0\1\47"+ + "\3\0\1\14\3\0\1\50\2\0\1\51"; private static int [] zzUnpackAction() { int [] result = new int[129]; @@ -239,49 +235,48 @@ public class _HtmlLexer implements FlexLexer { "\33\0\2\123\47\0\2\124\50\0\1\125\70\0\1\126"+ "\51\0\2\45\1\0\3\45\5\0\24\45\15\0\7\45"+ "\47\0\1\127\15\0\2\51\1\0\3\51\5\0\24\51"+ - "\15\0\7\51\43\0\1\130\20\0\3\55\1\0\4\55"+ - "\2\0\31\55\1\0\3\55\1\131\17\55\1\0\4\55"+ - "\2\0\27\55\1\132\1\55\1\0\3\55\1\131\57\55"+ - "\1\130\3\55\1\131\14\55\41\0\1\133\62\0\1\62"+ - "\64\0\1\134\22\0\43\70\1\0\2\70\1\135\60\70"+ - "\1\71\20\70\1\0\2\73\1\0\3\73\5\0\24\73"+ - "\15\0\7\73\1\0\3\100\1\0\1\100\5\0\25\100"+ - "\4\0\2\100\7\0\7\100\43\0\1\136\21\0\2\105"+ - "\1\0\3\105\5\0\24\105\15\0\7\105\1\0\2\106"+ - "\1\0\3\106\5\0\24\106\15\0\7\106\6\0\1\137"+ - "\5\0\1\140\50\0\1\141\2\0\1\141\2\0\1\142"+ - "\4\0\24\141\15\0\7\141\42\112\1\143\21\112\1\0"+ - "\2\113\1\0\3\113\5\0\24\113\14\0\1\144\7\113"+ - "\2\0\1\145\57\0\1\146\2\0\2\113\1\0\3\113"+ - "\5\0\5\113\1\147\16\113\14\0\1\144\7\113\1\0"+ - "\2\113\1\0\3\113\5\0\10\113\1\150\3\113\1\151"+ - "\7\113\14\0\1\144\7\113\1\0\2\113\1\0\3\113"+ - "\5\0\20\113\1\152\3\113\14\0\1\144\7\113\1\0"+ - "\2\113\1\0\3\113\5\0\22\113\1\153\1\113\14\0"+ - "\1\144\7\113\35\0\2\154\54\0\2\155\36\0\1\125"+ - "\37\0\1\156\70\0\1\157\13\0\43\55\1\0\3\55"+ - "\1\131\14\55\3\132\1\160\4\132\2\160\30\132\1\161"+ - "\1\160\3\132\1\162\14\132\10\133\1\0\31\133\1\163"+ - "\21\133\11\134\1\0\30\134\1\163\21\134\43\70\1\0"+ - "\20\70\6\0\1\164\72\0\2\165\46\0\2\141\1\0"+ - "\3\141\5\0\24\141\15\0\7\141\1\0\2\142\1\0"+ - "\3\142\5\0\24\142\15\0\7\142\2\0\1\145\51\0"+ - "\1\166\11\0\1\167\11\0\1\167\2\0\1\167\5\0"+ - "\1\167\7\0\2\167\17\0\1\167\4\0\1\167\1\0"+ - "\2\113\1\0\3\113\5\0\24\113\14\0\1\166\7\113"+ - "\1\0\2\113\1\0\3\113\5\0\2\113\1\170\21\113"+ - "\14\0\1\144\7\113\1\0\2\113\1\0\3\113\5\0"+ - "\10\113\1\147\13\113\14\0\1\144\7\113\1\0\2\113"+ - "\1\0\3\113\5\0\2\113\1\115\21\113\14\0\1\144"+ - "\7\113\1\0\2\113\1\0\3\113\5\0\24\113\14\0"+ - "\1\144\2\113\1\151\4\113\31\0\2\171\62\0\2\172"+ - "\31\0\42\160\1\163\21\160\42\132\1\161\1\160\3\132"+ - "\1\162\14\132\17\0\1\173\46\0\1\167\11\0\1\167"+ - "\2\0\1\167\5\0\1\167\7\0\2\167\15\0\1\166"+ - "\1\0\1\167\4\0\1\167\1\0\2\113\1\0\3\113"+ - "\5\0\24\113\14\0\1\144\2\113\1\147\4\113\37\0"+ - "\1\174\44\0\2\175\61\0\1\176\66\0\1\177\64\0"+ - "\2\200\64\0\1\201\36\0"; + "\15\0\7\51\43\0\1\130\20\0\3\55\1\0\37\55"+ + "\1\0\3\55\1\131\17\55\1\0\35\55\1\132\1\55"+ + "\1\0\3\55\1\131\17\55\1\0\37\55\1\130\3\55"+ + "\1\131\14\55\41\0\1\133\62\0\1\62\64\0\1\134"+ + "\22\0\43\70\1\0\2\70\1\135\60\70\1\71\20\70"+ + "\1\0\2\73\1\0\3\73\5\0\24\73\15\0\7\73"+ + "\1\0\3\100\1\0\1\100\5\0\25\100\4\0\2\100"+ + "\7\0\7\100\43\0\1\136\21\0\2\105\1\0\3\105"+ + "\5\0\24\105\15\0\7\105\1\0\2\106\1\0\3\106"+ + "\5\0\24\106\15\0\7\106\6\0\1\137\5\0\1\140"+ + "\50\0\1\141\2\0\1\141\2\0\1\142\4\0\24\141"+ + "\15\0\7\141\42\112\1\143\21\112\1\0\2\113\1\0"+ + "\3\113\5\0\24\113\14\0\1\144\7\113\2\0\1\145"+ + "\57\0\1\146\2\0\2\113\1\0\3\113\5\0\5\113"+ + "\1\147\16\113\14\0\1\144\7\113\1\0\2\113\1\0"+ + "\3\113\5\0\10\113\1\150\3\113\1\151\7\113\14\0"+ + "\1\144\7\113\1\0\2\113\1\0\3\113\5\0\20\113"+ + "\1\152\3\113\14\0\1\144\7\113\1\0\2\113\1\0"+ + "\3\113\5\0\22\113\1\153\1\113\14\0\1\144\7\113"+ + "\35\0\2\154\54\0\2\155\36\0\1\125\37\0\1\156"+ + "\70\0\1\157\13\0\43\55\1\0\3\55\1\131\14\55"+ + "\3\132\1\160\36\132\1\161\1\160\3\132\1\162\14\132"+ + "\10\133\1\0\31\133\1\163\21\133\11\134\1\0\30\134"+ + "\1\163\21\134\43\70\1\0\20\70\6\0\1\164\72\0"+ + "\2\165\46\0\2\141\1\0\3\141\5\0\24\141\15\0"+ + "\7\141\1\0\2\142\1\0\3\142\5\0\24\142\15\0"+ + "\7\142\2\0\1\145\51\0\1\166\11\0\1\167\11\0"+ + "\1\167\2\0\1\167\5\0\1\167\7\0\2\167\17\0"+ + "\1\167\4\0\1\167\1\0\2\113\1\0\3\113\5\0"+ + "\24\113\14\0\1\166\7\113\1\0\2\113\1\0\3\113"+ + "\5\0\2\113\1\170\21\113\14\0\1\144\7\113\1\0"+ + "\2\113\1\0\3\113\5\0\10\113\1\147\13\113\14\0"+ + "\1\144\7\113\1\0\2\113\1\0\3\113\5\0\2\113"+ + "\1\115\21\113\14\0\1\144\7\113\1\0\2\113\1\0"+ + "\3\113\5\0\24\113\14\0\1\144\2\113\1\151\4\113"+ + "\31\0\2\171\62\0\2\172\31\0\42\160\1\163\21\160"+ + "\42\132\1\161\1\160\3\132\1\162\14\132\17\0\1\173"+ + "\46\0\1\167\11\0\1\167\2\0\1\167\5\0\1\167"+ + "\7\0\2\167\15\0\1\166\1\0\1\167\4\0\1\167"+ + "\1\0\2\113\1\0\3\113\5\0\24\113\14\0\1\144"+ + "\2\113\1\147\4\113\37\0\1\174\44\0\2\175\61\0"+ + "\1\176\66\0\1\177\64\0\2\200\64\0\1\201\36\0"; private static int [] zzUnpackTrans() { int [] result = new int[4576]; @@ -325,14 +320,14 @@ public class _HtmlLexer implements FlexLexer { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\1\1\5\0\1\1\2\0\1\1\5\0\2\1\1\11"+ - "\4\1\1\11\5\1\1\11\1\1\1\11\3\1\2\11"+ - "\1\1\1\11\3\1\1\11\1\1\1\11\1\1\2\11"+ - "\2\1\2\11\5\1\1\11\2\1\1\11\2\1\1\11"+ - "\4\1\1\11\2\1\1\0\1\11\1\1\15\0\2\11"+ - "\2\1\3\0\1\11\2\0\2\1\2\11\11\0\2\11"+ - "\1\0\2\1\2\11\1\0\1\11\3\0\1\11\3\0"+ - "\1\11\2\0\1\11"; + "\1\1\10\0\1\1\5\0\2\1\1\11\4\1\1\11"+ + "\5\1\1\11\1\1\1\11\3\1\2\11\1\1\1\11"+ + "\3\1\1\11\1\1\1\11\1\1\2\11\2\1\2\11"+ + "\5\1\1\11\2\1\1\11\2\1\1\11\4\1\1\11"+ + "\2\1\1\0\1\11\1\1\15\0\2\11\2\1\3\0"+ + "\1\11\2\0\2\1\2\11\11\0\2\11\1\0\2\1"+ + "\2\11\1\0\1\11\3\0\1\11\3\0\1\11\2\0"+ + "\1\11"; private static int [] zzUnpackAttribute() { int [] result = new int[129]; @@ -605,14 +600,14 @@ public class _HtmlLexer implements FlexLexer { zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; - zzState = zzLexicalState; + zzState = ZZ_LEXSTATE[zzLexicalState]; zzForAction: { while (true) { if (zzCurrentPosL < zzEndReadL) - zzInput = zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++]:zzBufferL.charAt(zzCurrentPosL++); + zzInput = (zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++] : zzBufferL.charAt(zzCurrentPosL++)); else if (zzAtEOF) { zzInput = YYEOF; break zzForAction; @@ -632,7 +627,7 @@ public class _HtmlLexer implements FlexLexer { break zzForAction; } else { - zzInput = zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++]:zzBufferL.charAt(zzCurrentPosL++); + zzInput = (zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++] : zzBufferL.charAt(zzCurrentPosL++)); } } int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; @@ -665,7 +660,7 @@ public class _HtmlLexer implements FlexLexer { { return XmlTokenType.XML_TAG_CHARACTERS; } case 44: break; - case 15: + case 14: { yybegin(ATTRIBUTE_VALUE_START); return XmlTokenType.XML_EQ; } case 45: break; @@ -673,7 +668,7 @@ public class _HtmlLexer implements FlexLexer { { return elTokenType; } case 46: break; - case 13: + case 12: { return XmlTokenType.XML_NAME; } case 47: break; @@ -681,7 +676,7 @@ public class _HtmlLexer implements FlexLexer { { yybegin(TAG_ATTRIBUTES); return XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER; } case 48: break; - case 10: + case 9: { yybegin(YYINITIAL); yypushback(1); break; } case 49: break; @@ -693,7 +688,7 @@ public class _HtmlLexer implements FlexLexer { { yybegin(COMMENT); return XmlTokenType.XML_COMMENT_START; } case 51: break; - case 4: + case 3: { return XmlTokenType.XML_REAL_WHITE_SPACE; } case 52: break; @@ -713,11 +708,11 @@ public class _HtmlLexer implements FlexLexer { { yybegin(END_TAG_NAME2); yypushback(yylength()); } case 56: break; - case 5: + case 4: { return XmlTokenType.XML_BAD_CHARACTER; } case 57: break; - case 14: + case 13: { yybegin(YYINITIAL); return XmlTokenType.XML_TAG_END; } case 58: break; @@ -737,7 +732,7 @@ public class _HtmlLexer implements FlexLexer { { yybegin(DOC_TYPE); return XmlTokenType.XML_DOCTYPE_START; } case 62: break; - case 3: + case 2: { return XmlTokenType.XML_PI_TARGET; } case 63: break; @@ -753,7 +748,7 @@ public class _HtmlLexer implements FlexLexer { { yybegin(PROCESSING_INSTRUCTION); return XmlTokenType.XML_PI_START; } case 66: break; - case 9: + case 8: { yybegin(C_COMMENT_START); return XmlTokenType.XML_CONDITIONAL_COMMENT_START; } case 67: break; @@ -761,7 +756,7 @@ public class _HtmlLexer implements FlexLexer { { yybegin(TAG_CHARACTERS); return XmlTokenType.XML_NAME; } case 68: break; - case 7: + case 6: { yybegin(YYINITIAL); return XmlTokenType.XML_DOCTYPE_END; } case 69: break; @@ -769,11 +764,11 @@ public class _HtmlLexer implements FlexLexer { { return XmlTokenType.XML_CHAR_ENTITY_REF; } case 70: break; - case 12: + case 11: { return XmlTokenType.XML_START_TAG_START; } case 71: break; - case 6: + case 5: { return XmlTokenType.XML_WHITE_SPACE; } case 72: break; @@ -801,7 +796,7 @@ public class _HtmlLexer implements FlexLexer { { yybegin(ATTRIBUTE_VALUE_SQ); return XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER; } case 78: break; - case 11: + case 10: { yybegin(TAG_ATTRIBUTES); return XmlTokenType.XML_NAME; } case 79: break; @@ -809,11 +804,11 @@ public class _HtmlLexer implements FlexLexer { { yybegin(START_TAG_NAME2); yypushback(yylength()); } case 80: break; - case 2: + case 15: { yybegin(TAG_ATTRIBUTES); return XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN; } case 81: break; - case 8: + case 7: { return XmlTokenType.XML_COMMENT_CHARACTERS; } case 82: break;