Merge branch 'master' of git.labs.intellij.net:idea/community
authorKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Fri, 13 Aug 2010 13:29:59 +0000 (17:29 +0400)
committerKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Fri, 13 Aug 2010 13:29:59 +0000 (17:29 +0400)
125 files changed:
java/compiler/impl/src/com/intellij/compiler/ant/CleanProject.java
java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkClasspath.java
java/compiler/impl/src/com/intellij/compiler/ant/ProjectBuild.java
java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java
java/compiler/openapi/src/com/intellij/compiler/ant/ChunkBuildExtension.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java
java/java-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspection.java
java/java-impl/src/com/intellij/lang/java/parser/DeclarationParser.java
java/java-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java
java/java-impl/src/com/intellij/lang/java/parser/ReferenceParser.java
java/java-impl/src/com/intellij/lang/java/parser/StatementParser.java
java/java-impl/src/com/intellij/psi/impl/java/stubs/index/JavaSuperClassNameOccurenceIndex.java
java/java-impl/src/com/intellij/psi/impl/search/JavaLikeSourceFilterScope.java [deleted file]
java/java-impl/src/com/intellij/psi/impl/source/parsing/ParseUtil.java
java/java-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java
java/java-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java
java/java-impl/src/com/intellij/refactoring/actions/AnonymousToInnerAction.java
java/java-impl/src/com/intellij/refactoring/actions/ChangeSignatureAction.java
java/java-impl/src/com/intellij/refactoring/actions/ConvertToInstanceMethodAction.java
java/java-impl/src/com/intellij/refactoring/actions/InvertBooleanAction.java
java/java-impl/src/com/intellij/refactoring/actions/MakeStaticAction.java
java/java-impl/src/com/intellij/refactoring/actions/TempWithQueryAction.java
java/java-impl/src/com/intellij/refactoring/typeMigration/actions/ChangeTypeSignatureAction.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg1.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg2.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg3.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg4.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeWithinItsWildcardBound.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardCastConversion.java [new file with mode: 0644]
java/java-tests/testData/psi/parser-full/commonParsing/UnclosedComment.java [new file with mode: 0644]
java/java-tests/testData/psi/parser-full/commonParsing/UnclosedComment.txt [new file with mode: 0644]
java/java-tests/testData/psi/parser-full/declarationParsing/class/Errors3.java [new file with mode: 0644]
java/java-tests/testData/psi/parser-full/declarationParsing/class/Errors3.txt [new file with mode: 0644]
java/java-tests/testData/psi/parser-full/declarationParsing/field/Errors.java [new file with mode: 0644]
java/java-tests/testData/psi/parser-full/declarationParsing/field/Errors.txt [new file with mode: 0644]
java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed0.java [moved from java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed.java with 100% similarity]
java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed0.txt [moved from java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed.txt with 94% similarity]
java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.java [new file with mode: 0644]
java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.txt [new file with mode: 0644]
java/java-tests/testData/psi/parser-partial/references/Type3.txt
java/java-tests/testData/psi/parser-partial/statements/BlockIncomplete0.txt
java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java
java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceTreeTest.java
java/java-tests/testSrc/com/intellij/dependencies/UsagesInAnalyzingDependenciesTest.java
java/java-tests/testSrc/com/intellij/lang/java/parser/CommonJavaParsingTest.java
java/java-tests/testSrc/com/intellij/lang/java/parser/declarationParsing/ClassParsingTest.java
java/java-tests/testSrc/com/intellij/lang/java/parser/declarationParsing/FieldParsingTest.java
java/java-tests/testSrc/com/intellij/lang/java/parser/partial/StatementParserTest.java
java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java
java/openapi/src/com/intellij/psi/util/TypesDistinctProver.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/lang/PsiBuilder.java
platform/lang-api/src/com/intellij/lang/WhitespacesAndCommentsProcessor.java [new file with mode: 0644]
platform/lang-api/src/com/intellij/psi/util/PsiTreeUtil.java
platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java
platform/lang-impl/src/com/intellij/codeInsight/generation/AutoIndentLinesHandler.java
platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java
platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java
platform/lang-impl/src/com/intellij/execution/ProgramRunnerUtil.java
platform/lang-impl/src/com/intellij/injected/editor/DocumentWindowImpl.java
platform/lang-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java
platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java
platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java
platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java
platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java
platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerRunnable.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/refactoring/actions/BaseRefactoringAction.java
platform/lang-impl/src/com/intellij/refactoring/actions/InlineAction.java
platform/lang-impl/src/com/intellij/refactoring/actions/SafeDeleteAction.java
platform/lang-impl/testSrc/com/intellij/lang/LightPsiBuilderTest.java
platform/platform-api/src/com/intellij/lang/Language.java
platform/platform-api/src/com/intellij/openapi/editor/Document.java
platform/platform-api/src/com/intellij/ui/HighlightableComponent.java
platform/platform-api/src/com/intellij/ui/table/TableView.java
platform/platform-api/src/com/intellij/util/IconUtil.java
platform/platform-impl/src/com/intellij/ide/actions/ScrollTreeToCenterAction.java
platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentDocument.java
platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapImpl.java
platform/platform-impl/src/com/intellij/ui/plaf/beg/IdeaMenuUI.java
platform/platform-resources/src/META-INF/XmlPlugin.xml
platform/testFramework/src/com/intellij/mock/MockDocument.java
platform/usageView/src/com/intellij/usages/ChunkExtractor.java
platform/util/src/com/intellij/util/containers/CollectionFactory.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesRenameContext.java [new file with mode: 0644]
plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ParameterClassCheckVisitor.java
plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java
plugins/git4idea/src/git4idea/checkout/branches/GitBranchConfigurations.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/GenerateManagedDependencyAction.java [moved from plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/GenerateAddManagedDependencyAction.java with 97% similarity]
plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/GenerateParentAction.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/MavenGenerateDomActionGroup.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/MavenGenerateTemplateAction.java [moved from plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/MavenCodeInsightGenerateAction.java with 62% similarity]
plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/extract/ExtractManagedDependenciesAction.java [moved from plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/extract/ExtractDependenciesAction.java with 51% similarity]
plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyAction.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenTreeAction.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenKeymapExtension.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenDomApplicationComponent.java [deleted file]
plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenEnvironmentRegistrar.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenLiveTemplateContextType.java [new file with mode: 0644]
plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenLiveTemplatesProvider.java [new file with mode: 0644]
plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachHandler.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/actions/MavenActionUtil.java
plugins/maven/src/main/resources/DomBundle.properties
plugins/maven/src/main/resources/META-INF/plugin.xml
plugins/maven/src/main/resources/liveTemplates/maven_generate_dom.xml [deleted file]
plugins/maven/src/main/resources/liveTemplates/maven_xml.xml [new file with mode: 0644]
plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/DependenciesImportingTest.java
xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlUnusedNamespaceInspection.java
xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingTemplate.java [deleted file]
xml/impl/src/com/intellij/codeInsight/template/zencoding/ZenCodingParser.java [new file with mode: 0644]
xml/impl/src/com/intellij/codeInsight/template/zencoding/ZenCodingTemplate.java
xml/impl/src/com/intellij/codeInsight/template/zencoding/filters/CommentZenCodingFilter.java
xml/impl/src/com/intellij/codeInsight/template/zencoding/filters/XslZenCodingFilter.java
xml/impl/src/com/intellij/codeInsight/template/zencoding/filters/ZenCodingGenerator.java [deleted file]
xml/impl/src/com/intellij/codeInsight/template/zencoding/generators/XmlZenCodingGenerator.java [moved from xml/impl/src/com/intellij/codeInsight/template/zencoding/filters/XmlZenCodingGenerator.java with 64% similarity]
xml/impl/src/com/intellij/codeInsight/template/zencoding/generators/XmlZenCodingGeneratorImpl.java [moved from xml/impl/src/com/intellij/codeInsight/template/zencoding/filters/XmlZenCodingGeneratorImpl.java with 86% similarity]
xml/impl/src/com/intellij/codeInsight/template/zencoding/generators/ZenCodingGenerator.java [new file with mode: 0644]
xml/impl/src/com/intellij/codeInsight/template/zencoding/nodes/GenerationNode.java
xml/impl/src/com/intellij/codeInsight/template/zencoding/tokens/TemplateToken.java
xml/impl/src/com/intellij/codeInsight/template/zencoding/tokens/XmlTemplateToken.java [deleted file]
xml/impl/src/com/intellij/xml/impl/XmlBraceMatcher.java
xml/impl/src/com/intellij/xml/refactoring/SchemaPrefixRenameHandler.java

index 730a2fe497a039782f1e5b1fc9827ce5aac86553..5613da9a6482ae35f99abbd8c91dcb134e54d21e 100644 (file)
  */
 package com.intellij.compiler.ant;
 
-import com.intellij.compiler.ant.taskdefs.Target;
 import com.intellij.compiler.ant.artifacts.ArtifactsGenerator;
+import com.intellij.compiler.ant.taskdefs.Target;
 import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
 import org.jetbrains.annotations.NotNull;
 
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * @author Eugene Zhuravlev
@@ -30,20 +34,17 @@ import java.io.PrintWriter;
 public class CleanProject extends Generator {
   private final Target myTarget;
 
-  public CleanProject(@NotNull GenerationOptions genOptions, @NotNull ArtifactsGenerator artifactsGenerator) {
-    StringBuffer dependencies = new StringBuffer();
+  public CleanProject(Project project, @NotNull GenerationOptions genOptions, @NotNull ArtifactsGenerator artifactsGenerator) {
+    List<String> dependencies = new ArrayList<String>();
     final ModuleChunk[] chunks = genOptions.getModuleChunks();
-    for (int idx = 0; idx < chunks.length; idx++) {
-      if (idx > 0) {
-        dependencies.append(", ");
-      }
-      dependencies.append(BuildProperties.getModuleCleanTargetName(chunks[idx].getName()));
+    for (ModuleChunk chunk : chunks) {
+      dependencies.add(BuildProperties.getModuleCleanTargetName(chunk.getName()));
     }
-    for (String target : artifactsGenerator.getCleanTargetNames()) {
-      if (dependencies.length() > 0) dependencies.append(", ");
-      dependencies.append(target);
+    dependencies.addAll(artifactsGenerator.getCleanTargetNames());
+    for (ChunkBuildExtension extension : ChunkBuildExtension.EP_NAME.getExtensions()) {
+      dependencies.addAll(extension.getCleanTargetNames(project, genOptions));
     }
-    myTarget = new Target(BuildProperties.TARGET_CLEAN, dependencies.toString(),
+    myTarget = new Target(BuildProperties.TARGET_CLEAN, StringUtil.join(dependencies, ", "),
                           CompilerBundle.message("generated.ant.build.clean.all.task.comment"), null);
   }
 
index 49dca1efd178b524cb1b1d3d64e1ba69964acaa3..c25df077e8a2de1732d3b124caf91c9b3a235988 100644 (file)
@@ -108,7 +108,9 @@ public class ModuleChunkClasspath extends Path {
                 return true;
               }
 
-              if (!generateRuntimeClasspath && !(orderEntry instanceof ModuleOrderEntry)) {
+              if (!generateRuntimeClasspath &&
+                  !(orderEntry instanceof ModuleOrderEntry) &&
+                  !(orderEntry instanceof ModuleSourceOrderEntry)) {
                 // needed for compilation classpath only
                 final boolean isExported = (orderEntry instanceof ExportableOrderEntry) && ((ExportableOrderEntry)orderEntry).isExported();
                 if (dependencyLevel > 0 && !isExported) {
@@ -119,7 +121,8 @@ public class ModuleChunkClasspath extends Path {
 
               if (orderEntry instanceof JdkOrderEntry) {
                 if (genOptions.forceTargetJdk && !generateRuntimeClasspath) {
-                  pathItems.add(new PathRefItem(BuildProperties.propertyRef(BuildProperties.getModuleChunkJdkClasspathProperty(chunk.getName()))));
+                  pathItems
+                    .add(new PathRefItem(BuildProperties.propertyRef(BuildProperties.getModuleChunkJdkClasspathProperty(chunk.getName()))));
                 }
               }
               else if (orderEntry instanceof ModuleOrderEntry) {
index c1e7ee712ae78f30eca4c7b98baf65579ac0fc5f..7d4c3d9d22164b2f98d5aba285dadc15bb37e69f 100644 (file)
@@ -61,6 +61,9 @@ public abstract class ProjectBuild extends Generator {
         }
       }
     }
+    for (ChunkBuildExtension extension : ChunkBuildExtension.EP_NAME.getExtensions()) {
+      extension.generateProjectTargets(project, genOptions, myAntProject);
+    }
 
     final Target initTarget = new Target(BuildProperties.TARGET_INIT, null,
                                          CompilerBundle.message("generated.ant.build.initialization.section.title"), null);
@@ -69,7 +72,7 @@ public abstract class ProjectBuild extends Generator {
 
     ArtifactsGenerator artifactsGenerator = new ArtifactsGenerator(project, genOptions);
 
-    myAntProject.add(new CleanProject(genOptions, artifactsGenerator), 1);
+    myAntProject.add(new CleanProject(project, genOptions, artifactsGenerator), 1);
 
     myAntProject.add(new Target(BuildProperties.TARGET_BUILD_MODULES, buildModulesTargetNames.toString(),
                                 CompilerBundle.message("generated.ant.build.build.all.modules.target.name"), null), 1);
index ce39f72ccdea4418cc72d1cdfc53f295c689d45a..3e41738c0d3ee5aa31686f336a758f9c8a920f88 100644 (file)
@@ -176,7 +176,7 @@ public class BackendCompilerWrapper {
       }
     }
     finally {
-      if (fileToDelete != null && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
+      if (fileToDelete != null) {
         FileUtil.asyncDelete(fileToDelete);
       }
     }
index 9693b333fe68ccc647fb9dab831c773d4184c1bc..eb896db7ffe7a34b0e4d8b0f6fb61cee6bf086aa 100644 (file)
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 public abstract class ChunkBuildExtension {
@@ -37,9 +38,16 @@ public abstract class ChunkBuildExtension {
 
   public abstract void process(Project project, ModuleChunk chunk, GenerationOptions genOptions, CompositeGenerator generator);
 
+  public void generateProjectTargets(Project project, GenerationOptions genOptions, CompositeGenerator generator) {
+  }
+
   public void generateProperties(final PropertyFileGenerator generator, final Project project, final GenerationOptions options) {
   }
 
+  public List<String> getCleanTargetNames(Project project, GenerationOptions genOptions) {
+    return Collections.emptyList();
+  }
+
   public static String[] getAllTargets(ModuleChunk chunk) {
     List<String> allTargets = new ArrayList<String>();
     final ChunkBuildExtension[] extensions = Extensions.getRootArea().getExtensionPoint(EP_NAME).getExtensions();
index d1826e0d45a9ad6e216258ab9e028367eebee141..e02b0564ca320abc04b3fc643b82eb2ae7470733 100644 (file)
@@ -172,13 +172,21 @@ public class GenericsHighlightUtil {
                                                                 final PsiSubstitutor substitutor,
                                                                 final PsiType type,
                                                                 final PsiElement typeElement2Highlight) {
-    if (!(type instanceof PsiClassType)) return null;
-    final PsiClass referenceClass = ((PsiClassType)type).resolve();
+    PsiType type2highlight = type;
+    if (type instanceof PsiWildcardType) {
+      if (((PsiWildcardType)type).isExtends()) {
+        type2highlight = ((PsiWildcardType)type).getExtendsBound();
+      } else if (((PsiWildcardType)type).isSuper()) {
+        type2highlight = ((PsiWildcardType)type).getSuperBound();
+      }
+    }
+    if (!(type2highlight instanceof PsiClassType)) return null;
+    final PsiClass referenceClass = ((PsiClassType)type2highlight).resolve();
     if (referenceClass == null) return null;
     final PsiClassType[] bounds = classParameter.getSuperTypes();
     for (PsiClassType type1 : bounds) {
       PsiType bound = substitutor.substitute(type1);
-      if (!TypeConversionUtil.isAssignable(bound, type, false)) {
+      if (!TypeConversionUtil.isAssignable(bound, type2highlight, false) && TypesDistinctProver.provablyDistinct(bound, type)) {
         PsiClass boundClass = bound instanceof PsiClassType ? ((PsiClassType)bound).resolve() : null;
 
         @NonNls final String messageKey = boundClass == null || referenceClass.isInterface() == boundClass.isInterface()
index 03656a3267f6ed6650c9b89446246a1b4729a651..151b9471f87653136cda30e3ac19c9a508137582 100644 (file)
@@ -320,7 +320,7 @@ public class Java15APIUsageInspection extends BaseJavaLocalInspectionTool {
     }
 
     private void registerError(PsiJavaCodeReferenceElement reference, LanguageLevel api) {
-      if (isInProject(reference)) {
+      if (reference != null && isInProject(reference)) {
         myHolder.registerProblem(reference, InspectionsBundle.message("inspection.1.5.problem.descriptor", getPresentable(api)));
       }
     }
index b5645b47f9cac929e9529e0d293935f441b6f935..fa31733fbcd33ef66673fb7fed1175d8c8ce2835 100644 (file)
@@ -414,13 +414,7 @@ public class DeclarationParser {
     }
 
     final IElementType tokenType = builder.getTokenType();
-    if (tokenType == JavaTokenType.SEMICOLON) {
-      builder.advanceLexer();
-    }
-    else if (tokenType == JavaTokenType.LBRACE) {
-      StatementParser.parseCodeBlock(builder);
-    }
-    else {
+    if (tokenType != JavaTokenType.SEMICOLON && tokenType != JavaTokenType.LBRACE) {
       final 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();
@@ -436,6 +430,12 @@ public class DeclarationParser {
       error.error(JavaErrorMessages.message("expected.lbrace.or.semicolon"));
     }
 
+    if (!expect(builder, JavaTokenType.SEMICOLON)) {
+      if (builder.getTokenType() == JavaTokenType.LBRACE) {
+        StatementParser.parseCodeBlock(builder);
+      }
+    }
+
     declaration.done(anno ? JavaElementType.ANNOTATION_METHOD : JavaElementType.METHOD);
     return declaration;
   }
@@ -799,6 +799,7 @@ public class DeclarationParser {
 
     parseAnnotationValue(builder);
 
+    boolean unclosed = false;
     while (true) {
       if (expect(builder, JavaTokenType.RBRACE)) {
         break;
@@ -808,11 +809,15 @@ public class DeclarationParser {
       }
       else {
         error(builder, JavaErrorMessages.message("expected.rbrace"));
+        unclosed = true;
         break;
       }
     }
 
     annoArray.done(JavaElementType.ANNOTATION_ARRAY_INITIALIZER);
+    if (unclosed) {
+      annoArray.setCustomEdgeProcessors(null, GREEDY_RIGHT_EDGE_PROCESSOR);
+    }
     return annoArray;
   }
 }
index 21e08de575e12b090d2268dffb5076ba709e2e61..69c41c98ddba4a4e49701e7374f1ac0daca6a4ce 100644 (file)
@@ -27,10 +27,18 @@ import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.List;
+
 
 public class JavaParserUtil {
   private static final Key<LanguageLevel> LANG_LEVEL_KEY = Key.create("JavaParserUtil.LanguageLevel");
 
+  public static final WhitespacesAndCommentsProcessor GREEDY_RIGHT_EDGE_PROCESSOR = new WhitespacesAndCommentsProcessor() {
+    public int process(final List<IElementType> tokens) {
+      return tokens.size();
+    }
+  };
+
   private JavaParserUtil() { }
 
   public static void setLanguageLevel(final PsiBuilder builder, final LanguageLevel level) {
@@ -124,7 +132,7 @@ public class JavaParserUtil {
 
       @Override
       public boolean eof() {
-        return getCurrentOffset() < stopAt || super.eof();
+        return getCurrentOffset() >= stopAt || super.eof();
       }
     };
   }
index 5208b8b8f6d452c5537eb514d534a2ecfc38290c..8a5163f1cfa2c0e931d50911b494a074162506d5 100644 (file)
@@ -104,13 +104,17 @@ public class ReferenceParser {
         DeclarationParser.parseAnnotations(builder);
       }
 
+      final PsiBuilder.Marker bracket = builder.mark();
       if (!expect(builder, JavaTokenType.LBRACKET)) {
+        bracket.drop();
         break;
       }
-      typeInfo.isArray = true;
-      if (!expectOrError(builder, JavaTokenType.RBRACKET, JavaErrorMessages.message("expected.rbracket"))) {
+      if (!expect(builder, JavaTokenType.RBRACKET)) {
+        bracket.rollbackTo();
         break;
       }
+      bracket.drop();
+      typeInfo.isArray = true;
 
       type = type.precede();
     }
index 5590f15fd28a757dabfdfb20df4ca9a132d5af74..7d592df0e92e1f6124ae78083a5e03eb62815232 100644 (file)
@@ -52,10 +52,12 @@ public class StatementParser {
     final PsiBuilder.Marker codeBlock = builder.mark();
     builder.advanceLexer();
 
+    boolean greedyBlock = false;
     int braceCount = 1;
     while (true) {
       final IElementType tokenType = builder.getTokenType();
       if (tokenType == null) {
+        greedyBlock = true;
         break;
       }
       if (tokenType == JavaTokenType.LBRACE) {
@@ -90,6 +92,7 @@ public class StatementParser {
           if (last == JavaTokenType.IDENTIFIER &&
               (prevLast == JavaTokenType.IDENTIFIER || ElementType.PRIMITIVE_TYPE_BIT_SET.contains(prevLast))) {
             position.rollbackTo();
+            greedyBlock = true;
             break;
           }
         }
@@ -98,6 +101,9 @@ public class StatementParser {
     }
 
     codeBlock.collapse(JavaElementType.CODE_BLOCK);
+    if (greedyBlock) {
+      codeBlock.setCustomEdgeProcessors(null, GREEDY_RIGHT_EDGE_PROCESSOR);
+    }
     return codeBlock;
   }
 
@@ -110,9 +116,12 @@ public class StatementParser {
 
     parseStatements(builder, (parseUntilEof ? BraceMode.TILL_LAST : BraceMode.TILL_FIRST));
 
-    expectOrError(builder, JavaTokenType.RBRACE, JavaErrorMessages.message("expected.rbrace"));
+    final boolean greedyBlock = !expectOrError(builder, JavaTokenType.RBRACE, JavaErrorMessages.message("expected.rbrace"));
 
     codeBlock.done(JavaElementType.CODE_BLOCK);
+    if (greedyBlock) {
+      codeBlock.setCustomEdgeProcessors(null, GREEDY_RIGHT_EDGE_PROCESSOR);
+    }
     return codeBlock;
   }
 
index f32b543f2e5c450e9b99aa0dea66646ab9e69ca2..d3c705336919c5457818100c7ef66f9f4e17a754 100644 (file)
@@ -21,7 +21,7 @@ package com.intellij.psi.impl.java.stubs.index;
 
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.PsiReferenceList;
-import com.intellij.psi.impl.search.JavaLikeSourceFilterScope;
+import com.intellij.psi.impl.search.JavaSourceFilterScope;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.stubs.StringStubIndexExtension;
 import com.intellij.psi.stubs.StubIndexKey;
@@ -42,7 +42,7 @@ public class JavaSuperClassNameOccurenceIndex extends StringStubIndexExtension<P
   }
 
   public Collection<PsiReferenceList> get(final String s, final Project project, final GlobalSearchScope scope) {
-    return super.get(s, project, new JavaLikeSourceFilterScope(scope, project));
+    return super.get(s, project, new JavaSourceFilterScope(scope));
   }
 
   @Override
diff --git a/java/java-impl/src/com/intellij/psi/impl/search/JavaLikeSourceFilterScope.java b/java/java-impl/src/com/intellij/psi/impl/search/JavaLikeSourceFilterScope.java
deleted file mode 100644 (file)
index 402ed0d..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2000-2010 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.
- */
-
-/*
- * @author max
- */
-package com.intellij.psi.impl.search;
-
-import com.intellij.lang.StdLanguages;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.LanguageFileType;
-import com.intellij.openapi.fileTypes.StdFileTypes;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ProjectFileIndex;
-import com.intellij.openapi.roots.ProjectRootManager;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.search.GlobalSearchScope;
-
-public class JavaLikeSourceFilterScope extends JavaSourceFilterScope {
-  private final GlobalSearchScope myDelegate;
-  private final ProjectFileIndex myIndex;
-
-  public JavaLikeSourceFilterScope(final GlobalSearchScope delegate, final Project project) {
-    super(delegate);
-    myDelegate = delegate;
-    myIndex = ProjectRootManager.getInstance(project).getFileIndex();
-  }
-
-  @Override
-  public boolean contains(final VirtualFile file) {
-    if (myDelegate != null && !myDelegate.contains(file)) {
-      return false;
-    }
-    final FileType fileType = file.getFileType();
-    return isJavaLikeFile(fileType) && myIndex.isInSourceContent(file) ||
-           StdFileTypes.CLASS == fileType && myIndex.isInLibraryClasses(file);
-  }
-
-  private static boolean isJavaLikeFile(final FileType fileType) {
-    return StdFileTypes.JAVA == fileType ||
-           fileType instanceof LanguageFileType &&
-           ((LanguageFileType)fileType).getLanguage().isKindOf(StdLanguages.JAVA);
-  }
-}
index c0d9cece2e5e899731b666a738f66f5713681f21..3809e11a824556d3543839882af9fc5fc67205e1 100644 (file)
@@ -96,10 +96,17 @@ public class ParseUtil extends ParseUtilBase {
       if (anImport == null || !isEmptyImportList(anImport)) return;
 
       final TreeElement next = (TreeElement)TreeUtil.skipElements(anImport.getTreeNext(), ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET);
-      if (next != null && next != anImport) {
+      if (next != null) {
         anImport.rawRemove();
         next.rawInsertBeforeMe(anImport);
       }
+      else {
+        final TreeElement last = (TreeElement)root.getLastChildNode();
+        if (last != null && last != anImport) {
+          anImport.rawRemove();
+          last.rawInsertAfterMe(anImport);
+        }
+      }
     }
 
     private static void bindComments(ASTNode root) {
index f3c1f5b0a5ba4747f7c5c0e0ec08704620405fa3..0aa7f85b7b61915ef3030c4d666d939e0491fd44 100644 (file)
@@ -118,7 +118,7 @@ public interface JavaElementType {
   IElementType CATCH_SECTION = new IJavaElementType("CATCH_SECTION");
 
   IElementType ANNOTATION_ARRAY_INITIALIZER = new IJavaElementType("ANNOTATION_ARRAY_INITIALIZER");
-  IElementType NAME_VALUE_PAIR = new IJavaElementType("NAME_VALUE_PAIR");
+  IElementType NAME_VALUE_PAIR = new IJavaElementType("NAME_VALUE_PAIR", true);
   IElementType ANNOTATION_PARAMETER_LIST = new IJavaElementType("ANNOTATION_PARAMETER_LIST", true);
   IElementType METHOD_RECEIVER = new IJavaElementType("METHOD_RECEIVER");
 
index 22c5be988e64e7eb704a60d6569b775937dba5d0..9b3393724e634ad6e14fae060c9aa83797adcc65 100644 (file)
@@ -61,7 +61,9 @@ public class PsiScopesUtil {
       if(scope instanceof PsiClass){
         processor.handleEvent(JavaScopeProcessorEvent.SET_CURRENT_FILE_CONTEXT, scope);
       }
-      if (!scope.processDeclarations(processor, state, prevParent, entrance)) return false;
+      if (!scope.processDeclarations(processor, state, prevParent, entrance)) {
+        return false; // resolved
+      }
 
       if (scope instanceof PsiModifierListOwner && !(scope instanceof PsiParameter/* important for not loading tree! */)){
         PsiModifierList modifierList = ((PsiModifierListOwner)scope).getModifierList();
index 52e6fec13ac5c0f27d5b02ffd21a6540804d0691..eb86ca9eff1b5783206cad9f08b3980ff76085a0 100644 (file)
@@ -1,25 +1,26 @@
-
 /*
- * 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.
- */
+* 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.
+*/
 package com.intellij.refactoring.actions;
 
 import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
-import com.intellij.psi.*;
+import com.intellij.psi.PsiAnonymousClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiNewExpression;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.refactoring.RefactoringActionHandler;
 import com.intellij.refactoring.anonymousToInner.AnonymousToInnerHandler;
@@ -33,14 +34,10 @@ public class AnonymousToInnerAction extends BaseRefactoringAction {
     return false;
   }
 
-  protected boolean isAvailableOnElementInEditor(final PsiElement element, final Editor editor) {
-    Document document = editor.getDocument();
-    PsiFile file = PsiDocumentManager.getInstance(element.getProject()).getPsiFile(document);
-    if (file != null) {
-      final PsiElement targetElement = file.findElementAt(editor.getCaretModel().getOffset());
-      if (PsiTreeUtil.getParentOfType(targetElement, PsiAnonymousClass.class) != null) {
-        return true;
-      }
+  protected boolean isAvailableOnElementInEditorAndFile(final PsiElement element, final Editor editor, PsiFile file) {
+    final PsiElement targetElement = file.findElementAt(editor.getCaretModel().getOffset());
+    if (PsiTreeUtil.getParentOfType(targetElement, PsiAnonymousClass.class) != null) {
+      return true;
     }
     if (PsiTreeUtil.getParentOfType(element, PsiAnonymousClass.class) != null) {
       return true;
index 4c21639f963a1e19f811beab862a2b3b9355ad13..a0612a770ea5af7f9c5ffe40641db929e4927215 100644 (file)
@@ -19,7 +19,6 @@ import com.intellij.lang.Language;
 import com.intellij.lang.LanguageRefactoringSupport;
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.actionSystem.LangDataKeys;
-import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.ScrollType;
 import com.intellij.openapi.project.Project;
@@ -38,10 +37,7 @@ public class ChangeSignatureAction extends BaseRefactoringAction {
     return elements.length == 1 && (elements[0] instanceof PsiMethod || elements[0] instanceof PsiClass);
   }
 
-  protected boolean isAvailableOnElementInEditor(final PsiElement element, final Editor editor) {
-    final Document document = editor.getDocument();
-    final PsiFile file = PsiDocumentManager.getInstance(element.getProject()).getPsiFile(document);
-    if (file == null) return false;
+  protected boolean isAvailableOnElementInEditorAndFile(final PsiElement element, final Editor editor, PsiFile file) {
     PsiElement targetMember = findTargetMember(file, editor);
     if (targetMember == null) return false;
     final ChangeSignatureHandler targetHandler = getChangeSignatureHandler(targetMember.getLanguage());
index 4150445b98b37843b151fdf14982f87a9f0302c7..1374d091578d4f2f2672a50a8f8b0b2da161ddca 100644 (file)
@@ -17,10 +17,7 @@ package com.intellij.refactoring.actions;
 
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.editor.Editor;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiIdentifier;
-import com.intellij.psi.PsiModifier;
+import com.intellij.psi.*;
 import com.intellij.refactoring.RefactoringActionHandler;
 import com.intellij.refactoring.convertToInstanceMethod.ConvertToInstanceMethodHandler;
 
@@ -36,7 +33,7 @@ public class ConvertToInstanceMethodAction extends BaseRefactoringAction {
     return elements.length == 1 && elements[0] instanceof PsiMethod;
   }
 
-  protected boolean isAvailableOnElementInEditor(PsiElement element, final Editor editor) {
+  protected boolean isAvailableOnElementInEditorAndFile(PsiElement element, final Editor editor, PsiFile file) {
     if (element instanceof PsiIdentifier) element = element.getParent();
     return element instanceof PsiMethod && ((PsiMethod) element).hasModifierProperty(PsiModifier.STATIC);
   }
index d959f412bc3a2ddf5f0a7e70035af012c3368b54..bbff15e1893abf20333baec009f26999a6043d1e 100644 (file)
@@ -17,10 +17,7 @@ package com.intellij.refactoring.actions;
 
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.editor.Editor;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiType;
-import com.intellij.psi.PsiVariable;
+import com.intellij.psi.*;
 import com.intellij.refactoring.RefactoringActionHandler;
 import com.intellij.refactoring.invertBoolean.InvertBooleanHandler;
 
@@ -36,7 +33,7 @@ public class InvertBooleanAction extends BaseRefactoringAction {
     return elements.length == 1 && (elements[0] instanceof PsiMethod || elements[0] instanceof PsiVariable);
   }
 
-  protected boolean isAvailableOnElementInEditor(final PsiElement element, final Editor editor) {
+  protected boolean isAvailableOnElementInEditorAndFile(final PsiElement element, final Editor editor, PsiFile file) {
     if (element instanceof PsiVariable) {
       return PsiType.BOOLEAN.equals(((PsiVariable) element).getType());
     }
index fc7a5d6b1f909029baa54e67fb04288a5659a7cc..78d52d95d12efe26a9e6665a6fd94f3d55c716a2 100644 (file)
@@ -39,7 +39,7 @@ public class MakeStaticAction extends BaseRefactoringAction {
     return (elements.length == 1) && (elements[0] instanceof PsiMethod) && !((PsiMethod)elements[0]).isConstructor();
   }
 
-  protected boolean isAvailableOnElementInEditor(PsiElement element, final Editor editor) {
+  protected boolean isAvailableOnElementInEditorAndFile(PsiElement element, final Editor editor, PsiFile file) {
     if (element instanceof PsiIdentifier) {
       element = element.getParent();
     }
index 6c63e30a3494e5838580080a71c1b14299d392e2..85128310f0b7ce291bde404fa31b30949f0a2dc5 100644 (file)
@@ -19,6 +19,7 @@ package com.intellij.refactoring.actions;
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
 import com.intellij.psi.PsiLocalVariable;
 import com.intellij.refactoring.RefactoringActionHandler;
 import com.intellij.refactoring.tempWithQuery.TempWithQueryHandler;
@@ -36,7 +37,7 @@ public class TempWithQueryAction extends BaseRefactoringAction{
     return new TempWithQueryHandler();
   }
 
-  protected boolean isAvailableOnElementInEditor(final PsiElement element, final Editor editor) {
+  protected boolean isAvailableOnElementInEditorAndFile(final PsiElement element, final Editor editor, PsiFile file) {
     return element instanceof PsiLocalVariable && ((PsiLocalVariable) element).getInitializer() != null; 
   }
 }
\ No newline at end of file
index 422a019fe7c34cbfa7a21d027bb2e6907ed9c414..d17f82a69a08b2291e4f2733b1bd08f689e804a0 100644 (file)
@@ -3,7 +3,6 @@ package com.intellij.refactoring.typeMigration.actions;
 import com.intellij.ide.DataManager;
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
@@ -35,15 +34,11 @@ public class ChangeTypeSignatureAction extends BaseRefactoringAction {
     return true;
   }
 
-  protected boolean isAvailableOnElementInEditor(final PsiElement element, final Editor editor) {
-    final Document document = editor.getDocument();
-    final PsiFile file = PsiDocumentManager.getInstance(element.getProject()).getPsiFile(document);
-    if (file != null) {
-      final PsiElement psiElement = file.findElementAt(editor.getCaretModel().getOffset());
-      final PsiReferenceParameterList referenceParameterList = PsiTreeUtil.getParentOfType(psiElement, PsiReferenceParameterList.class);
-      if (referenceParameterList != null) {
-        return referenceParameterList.getTypeArguments().length > 0;
-      }
+  protected boolean isAvailableOnElementInEditorAndFile(final PsiElement element, final Editor editor, PsiFile file) {
+    final PsiElement psiElement = file.findElementAt(editor.getCaretModel().getOffset());
+    final PsiReferenceParameterList referenceParameterList = PsiTreeUtil.getParentOfType(psiElement, PsiReferenceParameterList.class);
+    if (referenceParameterList != null) {
+      return referenceParameterList.getTypeArguments().length > 0;
     }
     return true;
   }
index d35733fde69ff1e3da102e1d194b6eba5eacc92a..1f674a9afcea4bc810cc1481a778b7f9fb68a7d2 100644 (file)
@@ -7,32 +7,32 @@ class Neg01<X extends Number> {
     }
 
     void test() {
-        Neg01<<error>String</error>> n1 = new Neg01<<error></error>>("" ); //new Foo<Integer> created
-        Neg01<? extends String> n2 = new Neg01<<error></error>>(""); //new Foo<Integer> created
-        Neg01<?> n3 = new Neg01<><error>("")</error>; //new Foo<Object> created
-        Neg01<? super String> n4 = new Neg01<<error></error>>(""); //new Foo<Object> created
+        Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n1 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("" ); //new Foo<Integer> created
+        Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n2 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
+        Neg01<?> n3 = new Neg01<><error descr="'Neg01(? extends java.lang.Number)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Object> created
+        Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n4 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
 
-        Neg01<<error>String</error>> n5 = new Neg01<<error></error>>("") {
+        Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n5 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
         }; //new Foo<Integer> created
-        Neg01<? extends String> n6 = new Neg01<<error></error>>("") {
+        Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n6 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
         }; //new Foo<Integer> created
-        Neg01<?> n7 = new Neg01<><error>("")</error> {
+        Neg01<?> n7 = new Neg01<><error descr="'Neg01(? extends java.lang.Number)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error> {
         }; //new Foo<Object> created
-        Neg01<? super String> n8 = new Neg01<<error></error>>("") {
+        Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n8 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
         }; //new Foo<Object> created
 
-        Neg01<<error>String</error>> n9 = new Neg01<<error></error>>("", ""); //new Foo<Integer> created
-        Neg01<? extends String> n10 = new Neg01<<error></error>>("", ""); //new Foo<Integer> created
-        Neg01<?> n11 = new Neg01<><error>("", "")</error>; //new Foo<Object> created
-        <error>Foo</error><? super String> n12 = new Neg01<<error></error>>("", ""); //new Foo<Object> created
+        Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n9 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+        Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n10 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+        Neg01<?> n11 = new Neg01<><error descr="'Neg01(? extends java.lang.Number, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Object> created
+        <error descr="Cannot resolve symbol 'Foo'">Foo</error><? super String> n12 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
 
-        Neg01<<error>String</error>> n13 = new Neg01<<error></error>>("", "") {
+        Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n13 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
         }; //new Foo<Integer> created
-        Neg01<? extends String> n14 = new Neg01<<error></error>>("", "") {
+        Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n14 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
         }; //new Foo<Integer> created
-        Neg01<?> n15 = new Neg01<><error>("", "")</error> {
+        Neg01<?> n15 = new Neg01<><error descr="'Neg01(? extends java.lang.Number, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error> {
         }; //new Foo<Object> created
-        Neg01<? super String> n16 = new Neg01<<error></error>>("", "") {
+        Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n16 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
         }; //new Foo<Object> created
     }
 }
index 0ca3233d4463e4e2043e2fd19299707b9f69ec60..13f71c79f4aa10c09ca158fb717bf123bec79e76 100644 (file)
@@ -9,62 +9,62 @@ class Neg02 {
     }
 
     void testSimple() {
-        Foo<<error>String</error>> f1 = new Foo<<error></error>>(""); //new Foo<Integer> created
-        Foo<? extends String> f2 = new Foo<<error></error>>(""); //new Foo<Integer> created
-        Foo<?> f3 = new Foo<><error>("")</error>; //new Foo<Object> created
-        Foo<? super String> f4 = new Foo<<error></error>>(""); //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
+        Foo<?> f3 = new Foo<><error descr="'Foo(? extends java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
 
-        Foo<<error>String</error>> f5 = new Foo<<error></error>>("") {
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
         }; //new Foo<Integer> created
-        Foo<? extends String> f6 = new Foo<<error></error>>("") {
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
         }; //new Foo<Integer> created
-        Foo<?> f7 = new Foo< ><error>("")</error> {
+        Foo<?> f7 = new Foo< ><error descr="'Foo(? extends java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error> {
         }; //new Foo<Object> created
-        Foo<? super String> f8 = new Foo<<error></error>>("") {
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
         }; //new Foo<Object> created
 
-        Foo<<error>String</error>> f9 = new Foo<<error></error>>("", ""); //new Foo<Integer> created
-        Foo<? extends String> f10 = new Foo<<error></error>>("", ""); //new Foo<Integer> created
-        Foo<?> f11 = new Foo< ><error>("", "")</error>; //new Foo<Object> created
-        Foo<? super String> f12 = new Foo<<error></error>>("", ""); //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f9 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+        Foo<?> f11 = new Foo< ><error descr="'Foo(? extends java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f12 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
 
-        Foo<<error>String</error>> f13 = new Foo<<error></error>>("", "") {
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f13 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
         }; //new Foo<Integer> created
-        Foo<? extends String> f14 = new Foo<<error></error>>("", "") {
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
         }; //new Foo<Integer> created
-        Foo<?> f15 = new Foo< ><error>("", "")</error> {
+        Foo<?> f15 = new Foo< ><error descr="'Foo(? extends java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error> {
         }; //new Foo<Object> created
-        Foo<? super String> f16 = new Foo<<error></error>>("", "") {
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f16 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
         }; //new Foo<Object> created
     }
 
     void testQualified() {
-        Foo<<error>String</error>> f1 = new Neg02.Foo<<error></error>>(""); //new Foo<Integer> created
-        Foo<? extends String> f2 = new Neg02.Foo<<error></error>>(""); //new Foo<Integer> created
-        Foo<?> f3 = new Neg02.Foo< ><error>("")</error>; //new Foo<Object> created
-        Foo<? super String> f4 = new Neg02.Foo<<error></error>>(""); //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
+        Foo<?> f3 = new Neg02.Foo< ><error descr="'Foo(? extends java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
 
-        Foo<<error>String</error>> f5 = new Neg02.Foo<<error></error>>("") {
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
         }; //new Foo<Integer> created
-        Foo<? extends String> f6 = new Neg02.Foo<<error></error>>("") {
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
         }; //new Foo<Integer> created
-        Foo<?> f7 = new Neg02.Foo< ><error>("")</error> {
+        Foo<?> f7 = new Neg02.Foo< ><error descr="'Foo(? extends java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error> {
         }; //new Foo<Object> created
-        Foo<? super String> f8 = new Neg02.Foo<<error></error>>("") {
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
         }; //new Foo<Object> created
 
-        Foo<<error>String</error>> f9 = new Neg02.Foo<<error></error>>("", ""); //new Foo<Integer> created
-        Foo<? extends String> f10 = new Neg02.Foo<<error></error>>("", ""); //new Foo<Integer> created
-        Foo<?> f11 = new Neg02.Foo< ><error>("", "")</error>; //new Foo<Object> created
-        Foo<? super String> f12 = new Neg02.Foo<<error></error>>("", ""); //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f9 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+        Foo<?> f11 = new Neg02.Foo< ><error descr="'Foo(? extends java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f12 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
 
-        Foo<<error>String</error>> f13 = new Neg02.Foo<<error></error>>("", "") {
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f13 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
         }; //new Foo<Integer> created
-        Foo<? extends String> f14 = new Neg02.Foo<<error></error>>("", "") {
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
         }; //new Foo<Integer> created
-        Foo<?> f15 = new Neg02.Foo< ><error>("", "")</error> {
+        Foo<?> f15 = new Neg02.Foo< ><error descr="'Foo(? extends java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error> {
         }; //new Foo<Object> created
-        Foo<? super String> f16 = new Neg02.Foo<<error></error>>("", "") {
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f16 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
         }; //new Foo<Object> created
     }
 }
index 69186f2bd65007f8749dfb69777caa407d08a77f..02cf6e5e1574719200f6708dada68f408af43bdc 100644 (file)
@@ -6,68 +6,68 @@ class Neg03<U> {
             }
 
             void testSimple() {
-                Foo<<error>String</error>> f1 = new Foo<<error></error>>(""); //new Foo<Integer> created
-                Foo<? extends String> f2 = new Foo<<error></error>>(""); //new Foo<Integer> created
-                Foo<?> f3 = new Foo<><error>("")</error>; //new Foo<Object> created
-                Foo<? super String> f4 = new Foo<<error></error>>(""); //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
+                Foo<?> f3 = new Foo<><error descr="'Foo(? extends java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
 
-                Foo<<error>String</error>> f5 = new Foo<<error></error>>(""){}; //new Foo<Integer> created
-                Foo<? extends String> f6 = new Foo<<error></error>>(""){}; //new Foo<Integer> created
-                Foo<?> f7 = new Foo<><error>("")</error>{}; //new Foo<Object> created
-                Foo<? super String> f8 = new Foo<<error></error>>(""){}; //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
+                Foo<?> f7 = new Foo<><error descr="'Foo(? extends java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>{}; //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Object> created
 
-                Foo<<error>String</error>> f9 = new Foo<<error></error>>("", ""); //new Foo<Integer> created
-                Foo<? extends String> f10 = new Foo<<error></error>>("", ""); //new Foo<Integer> created
-                Foo<?> f11 = new Foo<><error>("", "")</error>; //new Foo<Object> created
-                Foo<? super String> f12 = new Foo<<error></error>>("", ""); //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f9 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+                Foo<?> f11 = new Foo<><error descr="'Foo(? extends java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f12 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
 
-                Foo<<error>String</error>> f13 = new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
-                Foo<? extends String> f14 = new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
-                Foo<?> f15 = new Foo<><error>("", "")</error>{}; //new Foo<Object> created
-                Foo<? super String> f16 = new Foo<<error></error>>("", ""){}; //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f13 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
+                Foo<?> f15 = new Foo<><error descr="'Foo(? extends java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>{}; //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f16 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Object> created
             }
 
             void testQualified_1() {
-                Foo<<error>String</error>> f1 = new Neg03<U>.Foo<<error></error>>(""); //new Foo<Integer> created
-                Foo<? extends String> f2 = new Neg03<U>.Foo<<error></error>>(""); //new Foo<Integer> created
-                Foo<?> f3 = new Neg03<U>.Foo<><error>("")</error>; //new Foo<Object> created
-                Foo<? super String> f4 = new Neg03<U>.Foo<<error></error>>(""); //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
+                Foo<?> f3 = new Neg03<U>.Foo<><error descr="'Foo(? extends java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
 
-                Foo<<error>String</error>> f5 = new Neg03<U>.Foo<<error></error>>(""){}; //new Foo<Integer> created
-                Foo<? extends String> f6 = new Neg03<U>.Foo<<error></error>>(""){}; //new Foo<Integer> created
-                Foo<?> f7 = new Neg03<U>.Foo<><error>("")</error>{}; //new Foo<Object> created
-                Foo<? super String> f8 = new Neg03<U>.Foo<<error></error>>(""){}; //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
+                Foo<?> f7 = new Neg03<U>.Foo<><error descr="'Foo(? extends java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>{}; //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Object> created
 
-                Foo<<error>String</error>> f9 = new Neg03<U>.Foo<<error></error>>("", ""); //new Foo<Integer> created
-                Foo<? extends String> f10 = new Neg03<U>.Foo<<error></error>>("", ""); //new Foo<Integer> created
-                Foo<?> f11 = new Neg03<U>.Foo<><error>("", "")</error>; //new Foo<Object> created
-                Foo<? super String> f12 = new Neg03<U>.Foo<<error></error>>("", ""); //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f9 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+                Foo<?> f11 = new Neg03<U>.Foo<><error descr="'Foo(? extends java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f12 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
 
-                Foo<<error>String</error>> f13 = new Neg03<U>.Foo<<error></error>>("", ""){}; //new Foo<Integer> created
-                Foo<? extends String> f14 = new Neg03<U>.Foo<<error></error>>("", ""){}; //new Foo<Integer> created
-                Foo<?> f15 = new Neg03<U>.Foo<><error>("", "")</error>{}; //new Foo<Object> created
-                Foo<? super String> f16 = new Neg03<U>.Foo<<error></error>>("", ""){}; //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f13 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
+                Foo<?> f15 = new Neg03<U>.Foo<><error descr="'Foo(? extends java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>{}; //new Foo<Object> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f16 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Object> created
             }
 
             void testQualified_2(Neg03<U> n) {
-                Foo<<error>String</error>> f1 = n.new Foo<<error></error>>(""); //new Foo<Integer> created
-                Foo<? extends String> f2 = n.new Foo<<error></error>>(""); //new Foo<Integer> created
-                Foo<?> f3 = n.new Foo<><error>("")</error>; //new Foo<Integer> created
-                Foo<? super String> f4 = n.new Foo<<error></error>>(""); //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
+                Foo<?> f3 = n.new Foo<><error descr="'Foo(? extends java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
 
-                Foo<<error>String</error>> f5 = n.new Foo<<error></error>>(""){}; //new Foo<Integer> created
-                Foo<? extends String> f6 = n.new Foo<<error></error>>(""){}; //new Foo<Integer> created
-                Foo<?> f7 = n.new Foo<><error>("")</error>{}; //new Foo<Integer> created
-                Foo<? super String> f8 = n.new Foo<<error></error>>(""){}; //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
+                Foo<?> f7 = n.new Foo<><error descr="'Foo(? extends java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>{}; //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
 
-                Foo<<error>String</error>> f9 = n.new Foo<<error></error>>("", ""); //new Foo<Integer> created
-                Foo<? extends String> f10 = n.new Foo<<error></error>>("", ""); //new Foo<Integer> created
-                Foo<?> f11 = n.new Foo<><error>("", "")</error>; //new Foo<Integer> created
-                Foo<? super String> f12 = n.new Foo<<error></error>>("", ""); //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f9 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+                Foo<?> f11 = n.new Foo<><error descr="'Foo(? extends java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f12 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
 
-                Foo<<error>String</error>> f13 = n.new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
-                Foo<? extends String> f14 = n.new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
-                Foo<?> f15 = n.new Foo<><error>("", "")</error>{}; //new Foo<Integer> created
-                Foo<? super String> f16 = n.new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f13 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
+                Foo<?> f15 = n.new Foo<><error descr="'Foo(? extends java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>{}; //new Foo<Integer> created
+                Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f16 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
             }
         }
index bab5533aa149df1bf722c3ccb8cda9541ddd7a2f..000cb1c0b60ff48c6ba19f7291e16bda41377a37 100644 (file)
@@ -1,28 +1,28 @@
-        class Neg04 {
+class Neg04 {
 
-            void test() {
-                class Foo<V extends Number> {
-                    Foo(V x) {}
-                    <Z> Foo(V x, Z z) {}
-                }
-                Foo<<error>String</error>> n1 = new Foo<<error></error>>(""); //new Foo<Integer> created
-                Foo<? extends String> n2 = new Foo<<error></error>>(""); //new Foo<Integer> created
-                Foo<?> n3 = new Foo<><error>("")</error>; //new Foo<Object> created
-                Foo<? super String> n4 = new Foo<<error></error>>(""); //new Foo<Object> created
+    void test() {
+        class Foo<V extends Number> {
+            Foo(V x) {}
+            <Z> Foo(V x, Z z) {}
+        }
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n1 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n2 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
+        Foo<?> n3 = new Foo<><error descr="'Foo(? extends java.lang.Number)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n4 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
 
-                Foo<<error>String</error>> n5 = new Foo<<error></error>>(""){}; //new Foo<Integer> created
-                Foo<? extends String> n6 = new Foo<<error></error>>(""){}; //new Foo<Integer> created
-                Foo<?> n7 = new Foo<><error>("")</error>{}; //new Foo<Object> created
-                Foo<? super String> n8 = new Foo<<error></error>>(""){}; //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n5 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n6 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
+        Foo<?> n7 = new Foo<><error descr="'Foo(? extends java.lang.Number)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>{}; //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n8 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Object> created
 
-                Foo<<error>String</error>> n9 = new Foo<<error></error>>("", ""); //new Foo<Integer> created
-                Foo<? extends String> n10 = new Foo<<error></error>>("", ""); //new Foo<Integer> created
-                Foo<?> n11 = new Foo<><error>("", "")</error>; //new Foo<Object> created
-                Foo<? super String> n12 = new Foo<<error></error>>("", ""); //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n9 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n10 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
+        Foo<?> n11 = new Foo<><error descr="'Foo(? extends java.lang.Number, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n12 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
 
-                Foo<<error>String</error>> n13 = new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
-                Foo<? extends String> n14 = new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
-                Foo<?> n15 = new Foo<><error>("", "")</error>{}; //new Foo<Object> created
-                Foo<? super String> n16 = new Foo<<error></error>>("", ""){}; //new Foo<Object> created
-            }
-        }
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n13 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n14 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
+        Foo<?> n15 = new Foo<><error descr="'Foo(? extends java.lang.Number, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>{}; //new Foo<Object> created
+        Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n16 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Object> created
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeWithinItsWildcardBound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeWithinItsWildcardBound.java
new file mode 100644 (file)
index 0000000..8783ac3
--- /dev/null
@@ -0,0 +1,146 @@
+public class WithingBounds {
+    interface I {
+    }
+
+    void testE1() {
+        class A {
+        }
+        class B extends A {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<? extends B> pr;
+    }
+
+    void testERec1() {
+        class A {
+        }
+        class B<K> extends A {
+        }
+        class C<Y>{}
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<<error descr="Type parameter 'C' is not within its bound; should extend 'A'">?  extends C<? extends C></error>> pr;
+        ToCheckExtends<? extends B<? extends C>> pr1;
+    }
+
+
+    void testE2() {
+        class A {
+        }
+        class B {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<<error descr="Type parameter 'B' is not within its bound; should extend 'A'">? extends B</error>> pr;
+    }
+
+    void testE22() {
+        class B {
+        }
+        class A extends B {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<? extends B> pr;
+    }
+
+
+    void testE23() {
+        class A {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<? extends I> pr;
+    }
+
+    void testE24() {
+        final class A {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<<error descr="Type parameter 'WithingBounds.I' is not within its bound; should implement 'A'">? extends I</error>> pr;
+    }
+
+
+    //---------------------------------
+
+    void testE3() {
+        class A {
+        }
+        class ToCheckExtends<TTT extends I> {
+        }
+
+        ToCheckExtends<? extends A> pr;
+    }
+
+    void testE4() {
+        final class A {
+        }
+        class ToCheckExtends<TTT extends I> {
+        }
+
+        ToCheckExtends<<error descr="Type parameter 'A' is not within its bound; should implement 'WithingBounds.I'">? extends A</error>> pr;
+    }
+
+    void testE5() {
+        final class A implements I {
+        }
+        class ToCheckExtends<TTT extends I> {
+        }
+
+        ToCheckExtends<? extends A> pr;
+    }
+
+
+    interface AInterface {
+    }
+    void testE6() {
+
+        class ToCheckExtends<TTT extends I> {
+        }
+
+        ToCheckExtends<? extends AInterface> pr;
+    }
+
+    //-----------------------------
+
+    void testS1() {
+        class A {
+        }
+        class B extends A {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<? super B> pr;
+    }
+
+    void testS2() {
+        class A {
+        }
+        class B {
+        }
+        class ToCheckExtends<TTT extends A> {
+        }
+
+        ToCheckExtends<<error descr="Type parameter 'B' is not within its bound; should extend 'A'">? super B</error>> pr;
+    }
+
+    void testS3() {
+        class A {
+        }
+        class B extends A {
+        }
+        class ToCheckExtends<TTT extends B> {
+        }
+
+        ToCheckExtends<<error descr="Type parameter 'A' is not within its bound; should extend 'B'">? super A</error>> pr;
+    }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardCastConversion.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardCastConversion.java
new file mode 100644 (file)
index 0000000..fc0da5e
--- /dev/null
@@ -0,0 +1,466 @@
+public class Test {
+  interface A {}
+  interface B {}
+
+ //? extends A, ? extends B -----------------------------------------
+    void testEE1() {
+        class A {}
+        class B {}
+
+        W<? extends A> xx = null;
+        W<? extends B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A>>' to 'W<? extends B>'">(W<? extends B>) xx</error>;
+    }
+
+    void testEE2() {
+        class A {}
+        class B extends A {}
+
+        W<? extends A> xx = null;
+        W<? extends B> y = (W<? extends B>) xx;
+    }
+
+    void testEE21() {
+        class A {}
+        class B extends A {}
+
+        W<? extends B> xx = null;
+        W<? extends A> y = (W<? extends A>) xx;
+    }
+
+    void testEE211() {
+        class A {}
+        final class B extends A {}
+
+        W<? extends A> xx = null;
+        W<? extends B> y = (W<? extends B>) xx;
+    }
+
+    void test3EE() {
+        W<? extends A> xx = null;
+        W<? extends B> y = (W<? extends B>) xx;
+    }
+
+    void test4EE() {
+        class A {}
+        W<? extends A> xx = null;
+        W<? extends B> y = (W<? extends B>) xx;
+    }
+
+    void test41EE() {
+        class A {}
+        W<? extends B> xx = null;
+        W<? extends A> y = (W<? extends A>) xx;
+    }
+
+    void test411EE() {
+        final class A {}
+        W<? extends B> xx = null;
+        W<? extends A> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends Test.B>>' to 'W<? extends A>'">(W<? extends A>) xx</error>;
+    }
+
+    void test412EE() {
+        final class A implements B {}
+        W<? extends B> xx = null;
+        W<? extends A> y = (W<? extends A>) xx;
+    }
+
+    void test1() {
+        class A {}
+        class B {}
+
+        W<? super A> xx = null;
+        W<? super B> y = (W<? super B>) xx;
+    }
+
+    void test2() {
+        final class A {}
+        final class B {}
+
+        W<? super A> xx = null;
+        W<? super B> y = (W<? super B>) xx;
+    }
+
+   //? super A, ? super B -------------------------
+    void test3SS() {
+        W<? super A> xx = null;
+        W<? super B> y = (W<? super B>) xx;
+    }
+
+  //? extends A, ? super B -------------------------
+    void test1ES() {
+        class A {}
+        class B {}
+
+        W<? extends A> x = null;
+        W<? super B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A>>' to 'W<? super B>'">(W<? super B>) x</error>;
+    }
+
+    void test2ES() {
+        class A {}
+        class B extends A {}
+
+        W<? extends A> x = null;
+        W<? super B> y = (W<? super B>) x;
+    }
+
+    void test3ES() {
+        class A {}
+        class B extends A {}
+
+        W<? extends B> x = null;
+        W<? super A> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends B>>' to 'W<? super A>'">(W<? super A>) x</error>;
+    }
+
+
+    void test4ES() {
+        W<? extends B> x = null;
+        W<? super A> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends Test.B>>' to 'W<? super Test.A>'">(W<? super A>) x</error>;
+    }
+
+    void test5ES() {
+        final class B implements A {}
+
+        W<? extends A> x = null;
+        W<? super B> y = (W<? super B>) x;
+    }
+
+    void test6ES() {
+        final class B implements A {}
+
+        W<? extends B> x = null;
+        W<? super A> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends B>>' to 'W<? super Test.A>'">(W<? super A>) x</error>;
+    }
+
+  // ? extends A, B -----------------------
+    void test1EWC() {
+        class A {
+        }
+        class B {
+        }
+
+        W<? extends A> xx = null;
+        W<B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A>>' to 'W<B>'">(W<B>) xx</error>;
+    }
+
+    void test2EWC() {
+        class A {
+        }
+
+        W<? extends A> xx = null;
+        W<?> y = (W<?>) xx;
+    }
+
+    void test3EWC() {
+        class A {
+        }
+        class B extends A {
+        }
+
+        W<? extends A> xx = null;
+        W<B> y = (W<B>) xx;
+    }
+
+  // ? super A, B -----------------------
+    void test1SWC() {
+        class A {
+        }
+        class B {
+        }
+
+        W<? super A> xx = null;
+        W<B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? super A>>' to 'W<B>'">(W<B>) xx</error>;
+    }
+
+    void test2SWC() {
+        class A {
+        }
+
+        W<? super A> xx = null;
+        W<?> y = (W<?>) xx;
+    }
+
+    void test3SWC() {
+        class A {
+        }
+        class B extends A {
+        }
+
+        W<? super B> xx = null;
+        W<A> y = (W<A>) xx;
+    }
+
+  // ?, ? ------------------------------------------
+  void test1WWW() {
+    W<?> xx = null;
+    W<?> y = xx;
+  }
+
+  //? extends P<? extends A>, B --------------------
+
+    void test1EEWC() {
+        class A {
+        }
+        class B {
+        }
+
+        W<? extends P<? extends A>> xx = null;
+        W<? extends B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends P<? extends A>>>' to 'W<? extends B>'">(W<? extends B>) xx</error>;
+    }
+
+    void test2EEWC() {
+        class A {
+        }
+        class B extends P {
+        }
+
+        W<? extends P<? extends A>> xx = null;
+        W<? extends B> y = (W<? extends B>) xx;
+    }
+
+     void test3EEWC() {
+        class A {
+        }
+        class B<TB> extends P<TB> {
+        }
+
+        W<? extends P<? extends A>> xx = null;
+        W<? extends B<? super A>> y = (W<? extends B<? super A>>) xx;
+    }
+
+
+     void test4EEWC() {
+        class A {
+        }
+        class B<TB> extends P<TB> {
+        }
+
+        W<? extends P<? extends A>> xx = null;
+        W<? extends B<?>> y = (W<? extends B<?>>) xx;
+    }
+
+    void test5EEWC() {
+        class A {
+        }
+        class B<TB> extends P<TB> {
+        }
+        class C {}
+
+        W<? extends P<? extends A>> xx = null;
+        W<? extends B<? extends C>> y = (W<? extends B<? extends C>>) xx;
+    }
+
+  //Array Types inside wildcards
+  void test1AE() {
+        class A {}
+        class B {}
+
+        W<? extends A[]> xx = null;
+        W<? extends B[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A[]>>' to 'W<? extends B[]>'">(W<? extends B[]>) xx</error>;
+    }
+
+    void test11AE() {
+        class A {}
+        class B {}
+
+        W<? extends A[]> xx = null;
+        W<? extends B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A[]>>' to 'W<? extends B>'">(W<? extends B>) xx</error>;
+    }
+
+     void test2AE() {
+        class A {}
+        class B extends A {}
+
+        W<? extends A[]> xx = null;
+        W<? extends B[]> y = (W<? extends B[]>) xx;
+    }
+
+    void test21AE() {
+        class A {}
+        class B extends A {}
+
+        W<? extends A[]> xx = null;
+        W<? extends B> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A[]>>' to 'W<? extends B>'">(W<? extends B>) xx</error>;
+    }
+
+
+
+    void testIntAE() {
+
+        W<? extends A[]> xx = null;
+        W<? extends B[]> y = (W<? extends B[]>) xx;
+    }
+
+    void testInt1AE() {
+
+        W<? extends A[]> xx = null;
+        W<? extends B[][]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends Test.A[]>>' to 'W<? extends Test.B[][]>'">(W<? extends B[][]>) xx</error>;
+    }
+
+    void testASS() {
+        class A {}
+        class B {}
+
+        W<? super A[]> xx = null;
+        W<? super B[]> y = (W<? super B[]>) xx;
+    }
+
+    void test1AES() {
+        class A {}
+        class B {}
+
+        W<? extends A[]> x = null;
+        W<? super B[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends A[]>>' to 'W<? super B[]>'">(W<? super B[]>) x</error>;
+    }
+
+    void test2AES() {
+        class A {}
+        class B extends A {}
+
+        W<? extends A[]> x = null;
+        W<? super B[]> y = (W<? super B[]>) x;
+    }
+
+    void test3AES() {
+        class A {}
+        class B extends A {}
+
+        W<? extends B[]> x = null;
+        W<? super A[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends B[]>>' to 'W<? super A[]>'">(W<? super A[]>) x</error>;
+    }
+
+
+
+    void test4AES() {
+        W<? extends B[]> x = null;
+        W<? super A[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends Test.B[]>>' to 'W<? super Test.A[]>'">(W<? super A[]>) x</error>;
+    }
+
+    void test5AES() {
+        final class B implements A {}
+
+        W<? extends A[]> x = null;
+        W<? super B[]> y = (W<? super B[]>) x;
+    }
+
+    void test6AES() {
+        final class B implements A {}
+
+        W<? extends B[]> x = null;
+        W<? super A[]> y = <error descr="Inconvertible types; cannot cast 'W<capture<? extends B[]>>' to 'W<? super Test.A[]>'">(W<? super A[]>) x</error>;
+    }
+
+  // type parameters extensions: D<T extends A>
+  void testT3() {
+        class A {
+        }
+        class D<T extends A > {
+            class B extends A {
+            }
+
+            void foo() {
+                D<? extends T> x = null;
+                D<? extends B> y = (D<? extends B>) x;
+            }
+
+        }
+
+    }
+
+    void testT4() {
+        class A {
+        }
+        class D<T extends A> {
+            class B {
+            }
+
+            void foo() {
+                D<? extends T> x = null;
+                D<<error descr="Type parameter 'B' is not within its bound; should extend 'A'">? extends B</error>> y = (D<<error descr="Type parameter 'B' is not within its bound; should extend 'A'">? extends B</error>>) x;
+            }
+
+        }
+
+    }
+
+
+    void testT5() {
+           class D<T> {
+               class B {
+               }
+
+               void foo() {
+                   D<? extends T> x = null;
+                   D<? extends B> y = (D<? extends B>) x;
+               }
+
+           }
+
+       }
+
+    void testT6() {
+        class A {
+        }
+        class D<T extends A> {
+            class B extends A {
+            }
+
+            void foo() {
+                D<? super T> x = null;
+                D<? super B> y = (D<?  super B>) x;
+            }
+
+        }
+
+    }
+
+     void testT7() {
+        class A {
+        }
+        class D<T extends A> {
+            class B extends A {
+            }
+
+            void foo() {
+                D<? extends T> x = null;
+                D<? super B> y = (D<?  super B>) x;
+            }
+
+        }
+
+    }
+
+     void testT8() {
+        class A {
+        }
+        class D<T extends A> {
+            class B extends A {
+            }
+
+            void foo() {
+                D<? super T> x = null;
+                D<? extends B> y = (D<? extends B>) x;
+            }
+
+        }
+
+    }
+
+     void testT9() {
+        class A {
+        }
+        class D<T> {
+            class B extends A {
+            }
+
+            void foo() {
+                D<? super T> x = null;
+                D<? extends A> y = (D<? extends B>) x;
+            }
+
+        }
+
+    }
+}
+
+class W<T> {}
+class P<L> {}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-full/commonParsing/UnclosedComment.java b/java/java-tests/testData/psi/parser-full/commonParsing/UnclosedComment.java
new file mode 100644 (file)
index 0000000..43141b9
--- /dev/null
@@ -0,0 +1,7 @@
+// unclosed comment
+/*
+
+import java.io.*;
+
+class a {
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-full/commonParsing/UnclosedComment.txt b/java/java-tests/testData/psi/parser-full/commonParsing/UnclosedComment.txt
new file mode 100644 (file)
index 0000000..2296d8e
--- /dev/null
@@ -0,0 +1,6 @@
+PsiJavaFile:UnclosedComment.java
+  PsiComment(END_OF_LINE_COMMENT)('// unclosed comment')
+  PsiWhiteSpace('\n')
+  PsiComment(C_STYLE_COMMENT)('/*\n\nimport java.io.*;\n\nclass a {\n}')
+  PsiImportList
+    <empty list>
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-full/declarationParsing/class/Errors3.java b/java/java-tests/testData/psi/parser-full/declarationParsing/class/Errors3.java
new file mode 100644 (file)
index 0000000..c3fe1cc
--- /dev/null
@@ -0,0 +1,5 @@
+class C {
+  public Object fa(int toDelete) sdfskdlfabcdavcd {
+    return null;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-full/declarationParsing/class/Errors3.txt b/java/java-tests/testData/psi/parser-full/declarationParsing/class/Errors3.txt
new file mode 100644 (file)
index 0000000..b71eb30
--- /dev/null
@@ -0,0 +1,60 @@
+PsiJavaFile:Errors3.java
+  PsiImportList
+    <empty list>
+  PsiClass:C
+    PsiModifierList:
+      <empty list>
+    PsiKeyword:class('class')
+    PsiWhiteSpace(' ')
+    PsiIdentifier:C('C')
+    PsiTypeParameterList
+      <empty list>
+    PsiReferenceList
+      <empty list>
+    PsiReferenceList
+      <empty list>
+    PsiWhiteSpace(' ')
+    PsiJavaToken:LBRACE('{')
+    PsiWhiteSpace('\n  ')
+    PsiMethod:fa
+      PsiModifierList:public
+        PsiKeyword:public('public')
+      PsiTypeParameterList
+        <empty list>
+      PsiWhiteSpace(' ')
+      PsiTypeElement:Object
+        PsiJavaCodeReferenceElement:Object
+          PsiIdentifier:Object('Object')
+          PsiReferenceParameterList
+            <empty list>
+      PsiWhiteSpace(' ')
+      PsiIdentifier:fa('fa')
+      PsiParameterList:(int toDelete)
+        PsiJavaToken:LPARENTH('(')
+        PsiParameter:toDelete
+          PsiModifierList:
+            <empty list>
+          PsiTypeElement:int
+            PsiKeyword:int('int')
+          PsiWhiteSpace(' ')
+          PsiIdentifier:toDelete('toDelete')
+        PsiJavaToken:RPARENTH(')')
+      PsiReferenceList
+        <empty list>
+      PsiWhiteSpace(' ')
+      PsiErrorElement:'{' or ';' expected
+        PsiIdentifier:sdfskdlfabcdavcd('sdfskdlfabcdavcd')
+      PsiWhiteSpace(' ')
+      PsiCodeBlock
+        PsiJavaToken:LBRACE('{')
+        PsiWhiteSpace('\n    ')
+        PsiReturnStatement
+          PsiKeyword:return('return')
+          PsiWhiteSpace(' ')
+          PsiLiteralExpression:null
+            PsiJavaToken:NULL_KEYWORD('null')
+          PsiJavaToken:SEMICOLON(';')
+        PsiWhiteSpace('\n  ')
+        PsiJavaToken:RBRACE('}')
+    PsiWhiteSpace('\n')
+    PsiJavaToken:RBRACE('}')
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-full/declarationParsing/field/Errors.java b/java/java-tests/testData/psi/parser-full/declarationParsing/field/Errors.java
new file mode 100644 (file)
index 0000000..533b0de
--- /dev/null
@@ -0,0 +1,3 @@
+class Test {
+  int[0];
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-full/declarationParsing/field/Errors.txt b/java/java-tests/testData/psi/parser-full/declarationParsing/field/Errors.txt
new file mode 100644 (file)
index 0000000..4424416
--- /dev/null
@@ -0,0 +1,31 @@
+PsiJavaFile:Errors.java
+  PsiImportList
+    <empty list>
+  PsiClass:Test
+    PsiModifierList:
+      <empty list>
+    PsiKeyword:class('class')
+    PsiWhiteSpace(' ')
+    PsiIdentifier:Test('Test')
+    PsiTypeParameterList
+      <empty list>
+    PsiReferenceList
+      <empty list>
+    PsiReferenceList
+      <empty list>
+    PsiWhiteSpace(' ')
+    PsiJavaToken:LBRACE('{')
+    PsiWhiteSpace('\n  ')
+    PsiModifierList:
+      <empty list>
+    PsiTypeElement:int
+      PsiKeyword:int('int')
+    PsiErrorElement:Identifier expected
+      <empty list>
+    PsiErrorElement:Unexpected token
+      PsiJavaToken:LBRACKET('[')
+      PsiJavaToken:INTEGER_LITERAL('0')
+      PsiJavaToken:RBRACKET(']')
+    PsiJavaToken:SEMICOLON(';')
+    PsiWhiteSpace('\n')
+    PsiJavaToken:RBRACE('}')
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.java b/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.java
new file mode 100644 (file)
index 0000000..4841f75
--- /dev/null
@@ -0,0 +1,4 @@
+class C {
+  String uiTest1 = new String("Test1"),
+         uiTest2<caret> = new String("Test2");
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.txt b/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.txt
new file mode 100644 (file)
index 0000000..ffe4704
--- /dev/null
@@ -0,0 +1,86 @@
+PsiJavaFile:MultiLineUnclosed1.java
+  PsiImportList
+    <empty list>
+  PsiClass:C
+    PsiModifierList:
+      <empty list>
+    PsiKeyword:class('class')
+    PsiWhiteSpace(' ')
+    PsiIdentifier:C('C')
+    PsiTypeParameterList
+      <empty list>
+    PsiReferenceList
+      <empty list>
+    PsiReferenceList
+      <empty list>
+    PsiWhiteSpace(' ')
+    PsiJavaToken:LBRACE('{')
+    PsiWhiteSpace('\n  ')
+    PsiField:uiTest1
+      PsiModifierList:
+        <empty list>
+      PsiTypeElement:String
+        PsiJavaCodeReferenceElement:String
+          PsiIdentifier:String('String')
+          PsiReferenceParameterList
+            <empty list>
+      PsiWhiteSpace(' ')
+      PsiIdentifier:uiTest1('uiTest1')
+      PsiWhiteSpace(' ')
+      PsiJavaToken:EQ('=')
+      PsiWhiteSpace(' ')
+      PsiNewExpression:new String("Test1")
+        PsiKeyword:new('new')
+        PsiReferenceParameterList
+          <empty list>
+        PsiWhiteSpace(' ')
+        PsiJavaCodeReferenceElement:String
+          PsiIdentifier:String('String')
+          PsiReferenceParameterList
+            <empty list>
+        PsiExpressionList
+          PsiJavaToken:LPARENTH('(')
+          PsiLiteralExpression:"Test1"
+            PsiJavaToken:STRING_LITERAL('"Test1"')
+          PsiJavaToken:RPARENTH(')')
+    PsiJavaToken:COMMA(',')
+    PsiErrorElement:Identifier expected
+      <empty list>
+    PsiWhiteSpace('\n         ')
+    PsiModifierList:
+      <empty list>
+    PsiTypeElement:uiTest2<caret>
+      PsiJavaCodeReferenceElement:uiTest2<caret>
+        PsiIdentifier:uiTest2('uiTest2')
+        PsiReferenceParameterList
+          PsiJavaToken:LT('<')
+          PsiTypeElement:caret
+            PsiJavaCodeReferenceElement:caret
+              PsiIdentifier:caret('caret')
+              PsiReferenceParameterList
+                <empty list>
+          PsiJavaToken:GT('>')
+    PsiErrorElement:Identifier expected
+      <empty list>
+    PsiWhiteSpace(' ')
+    PsiErrorElement:Unexpected token
+      PsiJavaToken:EQ('=')
+      PsiWhiteSpace(' ')
+      PsiKeyword:new('new')
+    PsiWhiteSpace(' ')
+    PsiMethod:String
+      PsiModifierList:
+        <empty list>
+      PsiTypeParameterList
+        <empty list>
+      PsiIdentifier:String('String')
+      PsiParameterList:("Test2")
+        PsiJavaToken:LPARENTH('(')
+        PsiErrorElement:Parameter expected
+          PsiJavaToken:STRING_LITERAL('"Test2"')
+        PsiJavaToken:RPARENTH(')')
+      PsiReferenceList
+        <empty list>
+      PsiJavaToken:SEMICOLON(';')
+    PsiWhiteSpace('\n')
+    PsiJavaToken:RBRACE('}')
\ No newline at end of file
index 8f4c284f0e5f2237a588493e0fe22e58db79e7b8..2a9705d9b6020434e37aba5c278951a619da6ae3 100644 (file)
@@ -4,6 +4,5 @@ PsiJavaFile:Type3.java
       PsiKeyword:int('int')
     PsiJavaToken:LBRACKET('[')
     PsiJavaToken:RBRACKET(']')
-  PsiJavaToken:LBRACKET('[')
-  PsiErrorElement:']' expected
-    <empty list>
+  PsiErrorElement:Unparsed tokens
+    PsiJavaToken:LBRACKET('[')
\ No newline at end of file
index 3a5a40837d296939ee8cbdcc418263052ccce0b9..2cdd906d448117bb5c556a0a513442dcdb982491 100644 (file)
@@ -3,4 +3,5 @@ PsiJavaFile:BlockIncomplete0.java
     PsiJavaToken:LBRACE('{')
     PsiErrorElement:'}' expected
       <empty list>
-  PsiWhiteSpace(' ')
\ No newline at end of file
+    PsiWhiteSpace(' ')
+    PsiComment(C_STYLE_COMMENT)('/*}')
\ No newline at end of file
index 6f65c32a2e3d48890e4cb067a22d575aa7694a5e..c1bef6238ce32ede90870cf62d60d514521531a9 100644 (file)
@@ -18,9 +18,12 @@ public class KeywordCompletionTest extends LightCompletionTestCase {
     return JavaTestUtil.getJavaTestDataPath();
   }
 
+  private static final String[] ourPackageScopeKeywords =
+    new String[]{"package", "public", "private", "import", "final", "class", "interface", "abstract", "enum", null};
+
   public void testModifiersFileScope_1() throws Exception {
     configureByFile(BASE_PATH + "/fileScope-1.java");
-    testByCount(7, "package", "public", "private", "import", "final", "class", "interface", "abstract", null);
+    testByCount(8, ourPackageScopeKeywords);
   }
 
   private static final String[] ourClassScopeKeywords =
index 286dd2015d097adf8b7f101a4ffa616608935c17..797df150a2e5dc82928308bfd79291fa690a0552 100644 (file)
@@ -94,6 +94,8 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
   public void testOverrideAtLanguageLevel6() throws Exception { doTest(false); }
   public void testOverrideAtLanguageLevel5() throws Exception { doTest(false); }
   public void testSuperMethodCallWithErasure() throws Exception { doTest(false); }
+  public void testWildcardCastConversion() throws Exception { doTest(false); }
+  public void testTypeWithinItsWildcardBound() throws Exception { doTest(false); }
 
   public void testJavaUtilCollections() throws Exception {
     PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
index 279352dd80fa84f0fad1fa8bbaf9c0c3a8968548..7ae7027878297b7b3fa68246752d9f3c5cf23678 100644 (file)
@@ -25,7 +25,7 @@ import java.util.*;
  */
 public class SliceTreeTest extends LightDaemonAnalyzerTestCase {
   @Override protected Sdk getProjectJDK() {
-    return JavaSdkImpl.getMockJdk17("java 1.5");
+    return JavaSdkImpl.getMockJdk17();
   }
 
   private SliceTreeStructure configureTree(@NonNls final String name) throws Exception {
@@ -185,69 +185,69 @@ public class SliceTreeTest extends LightDaemonAnalyzerTestCase {
 
     checkStructure(newRoot, "Null Values\n" +
                             "  Value: o\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (52, 13) |l| |=| |d|;\n" +
-                            "        (15, 13) |set|(|o|)|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (52: 13) |l| |=| |d|;\n" +
+                            "        (15: 13) |set|(|o|)|;\n" +
                             "  Value: nu()\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (52, 13) |l| |=| |d|;\n" +
-                            "        (29, 13) |set|(|nu|(|)|)|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (52: 13) |l| |=| |d|;\n" +
+                            "        (29: 13) |set|(|nu|(|)|)|;\n" +
                             "  Value: t\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (52, 13) |l| |=| |d|;\n" +
-                            "        (46, 15) |x|.|set|(|t|)|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (52: 13) |l| |=| |d|;\n" +
+                            "        (46: 15) |x|.|set|(|t|)|;\n" +
                             "NotNull Values\n" +
                             "  Value: \"\"\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (52, 13) |l| |=| |d|;\n" +
-                            "        (19, 13) |set|(|CON|)|;\n" +
-                            "          (5, 39) |private| |final| |static| |String| |CON| |=| |\"\"|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (52: 13) |l| |=| |d|;\n" +
+                            "        (19: 13) |set|(|CON|)|;\n" +
+                            "          (5: 39) |private| |final| |static| |String| |CON| |=| |\"\"|;\n" +
                             "  Value: \"xxx\"\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (52, 13) |l| |=| |d|;\n" +
-                            "        (10, 13) |set|(|\"xxx\"|)|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (52: 13) |l| |=| |d|;\n" +
+                            "        (10: 13) |set|(|\"xxx\"|)|;\n" +
                             "  Value: new String()\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (52, 13) |l| |=| |d|;\n" +
-                            "        (17, 13) |set|(|new| |String|(|)|)|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (52: 13) |l| |=| |d|;\n" +
+                            "        (17: 13) |set|(|new| |String|(|)|)|;\n" +
                             "  Value: nn()\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (52, 13) |l| |=| |d|;\n" +
-                            "        (18, 13) |set|(|nn|(|)|)|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (52: 13) |l| |=| |d|;\n" +
+                            "        (18: 13) |set|(|nn|(|)|)|;\n" +
                             "  Value: nn\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (52, 13) |l| |=| |d|;\n" +
-                            "        (21, 13) |set|(|nn|)|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (52: 13) |l| |=| |d|;\n" +
+                            "        (21: 13) |set|(|nn|)|;\n" +
                             "  Value: g\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (52, 13) |l| |=| |d|;\n" +
-                            "        (27, 13) |set|(|g|)|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (52: 13) |l| |=| |d|;\n" +
+                            "        (27: 13) |set|(|g|)|;\n" +
                             "  Value: \"null\"\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (52, 13) |l| |=| |d|;\n" +
-                            "        (48, 15) |x|.|set|(|t| |==| |null| |?| |\"null\"| |:| |t|)|;\n" +
-                            "          (48, 27) |x|.|set|(|t| |==| |null| |?| |\"null\"| |:| |t|)|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (52: 13) |l| |=| |d|;\n" +
+                            "        (48: 15) |x|.|set|(|t| |==| |null| |?| |\"null\"| |:| |t|)|;\n" +
+                            "          (48: 27) |x|.|set|(|t| |==| |null| |?| |\"null\"| |:| |t|)|;\n" +
                             "  Value: t\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (52, 13) |l| |=| |d|;\n" +
-                            "        (48, 15) |x|.|set|(|t| |==| |null| |?| |\"null\"| |:| |t|)|;\n" +
-                            "          (48, 36) |x|.|set|(|t| |==| |null| |?| |\"null\"| |:| |t|)|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (52: 13) |l| |=| |d|;\n" +
+                            "        (48: 15) |x|.|set|(|t| |==| |null| |?| |\"null\"| |:| |t|)|;\n" +
+                            "          (48: 36) |x|.|set|(|t| |==| |null| |?| |\"null\"| |:| |t|)|;\n" +
                             "  Value: d\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (55, 13) |l| |=| |d|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (55: 13) |l| |=| |d|;\n" +
                             "Other Values\n" +
                             "  Value: g\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (52, 13) |l| |=| |d|;\n" +
-                            "        (11, 13) |set|(|g|)|;\n" +
-                            "        (24, 13) |set|(|other|)|;\n" +
-                            "          (23, 24) |String| |other| |=| |g| |==| |\"\"| |?| |CON| |:| |g|;\n" +
-                            "            (23, 40) |String| |other| |=| |g| |==| |\"\"| |?| |CON| |:| |g|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (52: 13) |l| |=| |d|;\n" +
+                            "        (11: 13) |set|(|g|)|;\n" +
+                            "        (24: 13) |set|(|other|)|;\n" +
+                            "          (23: 24) |String| |other| |=| |g| |==| |\"\"| |?| |CON| |:| |g|;\n" +
+                            "            (23: 40) |String| |other| |=| |g| |==| |\"\"| |?| |CON| |:| |g|;\n" +
                             "  Value: d\n" +
-                            "    (6, 12) |String| |l|;\n" +
-                            "      (52, 13) |l| |=| |d|;\n" +
-                            "        (30, 13) |set|(|hz|(|)|)|;\n" +
-                            "          (42, 16) |return| |d|;\n" +
+                            "    (6: 12) |String| |l|;\n" +
+                            "      (52: 13) |l| |=| |d|;\n" +
+                            "        (30: 13) |set|(|hz|(|)|)|;\n" +
+                            "          (42: 16) |return| |d|;\n" +
                             "");
   }
 
@@ -297,9 +297,9 @@ public class SliceTreeTest extends LightDaemonAnalyzerTestCase {
     checkStructure(newRoot,
         "Null Values\n" +
         "  Value: null\n" +
-        "    (2, 10) |String| |l|;\n" +
-        "      (4, 9) |l| |=| |null|;\n" +
-        "      (7, 9) |l| |=| |null|;\n" +
+        "    (2: 10) |String| |l|;\n" +
+        "      (4: 9) |l| |=| |null|;\n" +
+        "      (7: 9) |l| |=| |null|;\n" +
         ""
                    );
   }
index 8c42f1029bd6b6b3940e7a385a4cf5c6f651686c..2c4ac6c08cdcd471581fe29cb7c1a0e2804fb05a 100644 (file)
@@ -65,8 +65,16 @@ public class UsagesInAnalyzingDependenciesTest extends PsiTestCase{
     for (int i = 0; i < usagesInfos.length; i++) {
       psiUsages[i] = toString(usages[i]);
     }
-    checkResult(new String []{"(2, 14) import com.a.A;","(4, 3) A myA = new A();", "(4, 15) A myA = new A();", "(6, 9) myA.aa();",
-                              "(2, 14) import com.a.A;","(4, 3) A myA = new A();", "(4, 15) A myA = new A();", "(6, 9) myA.aa();"}, psiUsages);
+    checkResult(new String []{
+      "(2: 14) import com.a.A;",
+      "(4: 3) A myA = new A();",
+      "(4: 15) A myA = new A();",
+      "(6: 9) myA.aa();",
+
+      "(2: 14) import com.a.A;",
+      "(4: 3) A myA = new A();",
+      "(4: 15) A myA = new A();",
+      "(6: 9) myA.aa();"}, psiUsages);
   }
 
   private static String toString(Usage usage) {
@@ -96,7 +104,7 @@ public class UsagesInAnalyzingDependenciesTest extends PsiTestCase{
     for (int i = 0; i < usagesInfos.length; i++) {
       psiUsages[i] = toString(usages[i]);
     }
-    checkResult(new String []{"(4, 3) A myA = new A();", "(4, 15) A myA = new A();", "(5, 3) C myC = new C();", "(5, 15) C myC = new C();", "(7, 9) myA.aa();", "(8, 9) myC.cc();"}, psiUsages);
+    checkResult(new String []{"(4: 3) A myA = new A();", "(4: 15) A myA = new A();", "(5: 3) C myC = new C();", "(5: 15) C myC = new C();", "(7: 9) myA.aa();", "(8: 9) myC.cc();"}, psiUsages);
   }
 
   public void testForwardSimple(){
@@ -116,7 +124,7 @@ public class UsagesInAnalyzingDependenciesTest extends PsiTestCase{
     for (int i = 0; i < usagesInfos.length; i++) {
       psiUsages[i] = toString(usages[i]);
     }
-    checkResult(new String []{"(2, 3) B myB = new B();", "(2, 15) B myB = new B();", "(4, 9) myB.bb();"}, psiUsages);
+    checkResult(new String []{"(2: 3) B myB = new B();", "(2: 15) B myB = new B();", "(4: 9) myB.bb();"}, psiUsages);
   }
 
   private static void checkResult(final String[] usages, final String [] psiUsages) {
index e316ceffa277b661966baf1e343dc057f999b70b..df2c23887983882a24b76249bc2e2d0358c3b6ec 100644 (file)
@@ -24,4 +24,5 @@ public class CommonJavaParsingTest extends JavaParsingTestCase{
   public void testIncompleteCodeBlock() { doTest(true); }
   public void testImportListBug() { doTest(true); }
   public void testRefParamsAfterError() { doTest(true); }
+  public void testUnclosedComment() { doTest(true); }  // todo: fix
 }
\ No newline at end of file
index 900c9f2d2d8b66062d76678532c27801d60902f3..8230c535aeadd4b3f4bfe6caba45b2bd4cffa738 100644 (file)
@@ -34,10 +34,11 @@ public class ClassParsingTest extends JavaParsingTestCase {
   public void testLongClass() { doTest(false); }
   public void testIncompleteAnnotation() { doTest(true); }
 
-  public void testExtraOpeningBraceInMethod() { doTestDefaultParser(true); }  // todo: fix
+  public void testExtraOpeningBraceInMethod() { doTest(true); }
   public void testExtraClosingBraceInMethod() { doTest(true); }
 
   public void testErrors0() { doTest(true); }
   public void testErrors1() { doTest(true); }
   public void testErrors2() { doTest(true); }
+  public void testErrors3() { doTest(true); }
 }
index 938467bf618429d8efab8b97b44c19d6cc49d80a..f60cc67f98a77eaa3e9b242542631de4dc6b4b61 100644 (file)
@@ -18,7 +18,10 @@ public class FieldParsingTest extends JavaParsingTestCase {
   public void testUnclosedSemicolon() { doTest(true); }
   public void testMissingInitializerExpression() { doTest(true); }
 
-  public void testMultiLineUnclosed() { doTest(true); }
+  public void testMultiLineUnclosed0() { doTest(true); }
+  public void testMultiLineUnclosed1() { doTest(true); }
 
   public void testComplexInitializer() { doTest(true); }
+
+  public void testErrors() { doTest(true); }
 }
\ No newline at end of file
index ea0e0c77aa8f8f09b8b4112c01d397dca0b0a4f2..b22b28d8c6fe11bba6739441d5c1953a0e42aedc 100644 (file)
@@ -33,7 +33,7 @@ public class StatementParserTest extends JavaParsingTestCase {
   public void testBlockSimple() { doParserTest("{ {} }"); }
   public void testBlockEmpty() { doParserTest("{ ; }"); }
   public void testAnonymousInSmartCompletion() { doParserTest("{ new Foo(hash\n#) {};\n new Foo(hash\n#, bar) {};\n new Foo(hash\n#x) {}; }"); }
-  public void testBlockIncomplete0() { doParserTest("{ "); }
+  public void testBlockIncomplete0() { doParserTest("{ /*}"); }
   public void testBlockIncomplete1() { doParserTest("{ { }"); }
   public void testBlockIncomplete2() { doParserTest("{ else; catch; finally; }"); }
 
index 6ef8aa079bd72be529b7afd5992f985dff50739e..3b6e651396f1aa31c901856c9099a90ed79840bd 100644 (file)
@@ -328,12 +328,7 @@ public class TypeConversionUtil {
       PsiType typeArg1 = substitutor1.substitute(typeParameter);
       PsiType typeArg2 = substitutor2.substitute(typeParameter);
       if (typeArg1 == null || typeArg2 == null) return true;
-      if (typeArg1 instanceof PsiWildcardType || typeArg2 instanceof PsiWildcardType) return true;
-      if (typeArg1 instanceof PsiCapturedWildcardType || typeArg2 instanceof PsiCapturedWildcardType) return true;
-
-      if (typeArg1 instanceof PsiClassType && ((PsiClassType)typeArg1).resolve() instanceof PsiTypeParameter) return true;
-      if (typeArg2 instanceof PsiClassType && ((PsiClassType)typeArg2).resolve() instanceof PsiTypeParameter) return true;
-      if (!typeArg1.equals(typeArg2)) return false;
+      if (TypesDistinctProver.provablyDistinct(typeArg1, typeArg2)) return false;
     }
 
     return true;
diff --git a/java/openapi/src/com/intellij/psi/util/TypesDistinctProver.java b/java/openapi/src/com/intellij/psi/util/TypesDistinctProver.java
new file mode 100644 (file)
index 0000000..4b2b0a7
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.util;
+
+import com.intellij.psi.*;
+
+/**
+ * User: anna
+ * Date: Aug 12, 2010
+ */
+public class TypesDistinctProver {
+  private TypesDistinctProver() {
+  }
+
+  public static boolean provablyDistinct(PsiType type1, PsiType type2) {
+    if (type1 instanceof PsiWildcardType) {
+      if (type2 instanceof PsiWildcardType) {
+        return provablyDistinct((PsiWildcardType)type1, (PsiWildcardType)type2);
+      }
+
+      if (type2 instanceof PsiCapturedWildcardType) {
+        return provablyDistinct((PsiWildcardType)type1, ((PsiCapturedWildcardType)type2).getWildcard());
+      }
+
+      if (type2 instanceof PsiClassType) {
+        final PsiClass psiClass2 = PsiUtil.resolveClassInType(type2);
+        if (psiClass2 == null) return false;
+
+        if (((PsiWildcardType)type1).isExtends()) {
+          final PsiType extendsBound = ((PsiWildcardType)type1).getExtendsBound();
+          if (extendsBound.getArrayDimensions() > 0) return true;
+          final PsiClass boundClass1 = PsiUtil.resolveClassInType(TypeConversionUtil.erasure(extendsBound));
+          if (boundClass1 == null) return false;
+          return proveExtendsBoundsDistinct(type1, type2, boundClass1, psiClass2);
+        }
+
+        if (((PsiWildcardType)type1).isSuper()) {
+          final PsiType superBound = ((PsiWildcardType)type1).getSuperBound();
+          if (superBound.getArrayDimensions() > 0) return true;
+          final PsiClass boundClass1 = PsiUtil.resolveClassInType(TypeConversionUtil.erasure(superBound));
+          if (boundClass1 == null || boundClass1 instanceof PsiTypeParameter) return false;
+          return !boundClass1.isInheritor(psiClass2, true);
+        }
+
+        final PsiType bound = ((PsiWildcardType)type1).getBound();
+        return bound != null && !bound.equals(psiClass2);
+      }
+    }
+    if (type1 instanceof PsiCapturedWildcardType) return provablyDistinct(((PsiCapturedWildcardType)type1).getWildcard(), type2);
+
+    if (type2 instanceof PsiWildcardType || type2 instanceof PsiCapturedWildcardType) return provablyDistinct(type2, type1);
+
+    if (type1 instanceof PsiClassType && ((PsiClassType)type1).resolve() instanceof PsiTypeParameter) return false;
+    if (type2 instanceof PsiClassType && ((PsiClassType)type2).resolve() instanceof PsiTypeParameter) return false;
+
+    return !type1.equals(type2);
+  }
+
+  public static boolean provablyDistinct(PsiWildcardType type1, PsiWildcardType type2) {
+    if (type1.isSuper() && type2.isSuper()) return false;
+    if (type1.isExtends() && type2.isExtends()) {
+      final PsiType extendsBound1 = type1.getExtendsBound();
+      final PsiType extendsBound2 = type2.getExtendsBound();
+      if (extendsBound1.getArrayDimensions() != extendsBound2.getArrayDimensions()) return true;
+
+      final PsiClass boundClass1 = PsiUtil.resolveClassInType(extendsBound1);
+      final PsiClass boundClass2 = PsiUtil.resolveClassInType(extendsBound2);
+      if (boundClass1 != null && boundClass2 != null) {
+        return proveExtendsBoundsDistinct(type1, type2, boundClass1, boundClass2);
+      }
+      return provablyDistinct(extendsBound1, extendsBound2);
+    }
+    if (type2.isExtends()) return provablyDistinct(type2, type1);
+    if (type1.isExtends() && type2.isSuper()) {
+      final PsiType extendsBound = type1.getExtendsBound();
+      final PsiType superBound = type2.getSuperBound();
+      if (extendsBound.getArrayDimensions() != superBound.getArrayDimensions()) return true;
+
+      final PsiClass extendsBoundClass = PsiUtil.resolveClassInType(extendsBound);
+      final PsiClass superBoundClass = PsiUtil.resolveClassInType(superBound);
+      if (extendsBoundClass != null && superBoundClass != null) {
+        if (extendsBoundClass instanceof PsiTypeParameter) {
+          return try2ProveTypeParameterDistinct(type2, extendsBoundClass);
+        }
+        if (superBoundClass instanceof PsiTypeParameter) return false;
+        return !superBoundClass.isInheritor(extendsBoundClass, true);
+      }
+      return true;
+    }
+    return !type1.equals(type2);
+  }
+
+  public static boolean proveExtendsBoundsDistinct(PsiType type1,
+                                                    PsiType type2,
+                                                    PsiClass boundClass1,
+                                                    PsiClass boundClass2) {
+    if (boundClass1.isInterface() && boundClass2.isInterface()) return false;
+    if (boundClass1.isInterface()) {
+      return !(boundClass2.hasModifierProperty(PsiModifier.FINAL) ? boundClass2.isInheritor(boundClass1, true) : true);
+    }
+    if (boundClass2.isInterface()) {
+      return !(boundClass1.hasModifierProperty(PsiModifier.FINAL) ? boundClass1.isInheritor(boundClass2, true) : true);
+    }
+
+    if (boundClass1 instanceof PsiTypeParameter) {
+      return try2ProveTypeParameterDistinct(type2, boundClass1);
+    }
+
+    if (boundClass2 instanceof PsiTypeParameter) {
+      return try2ProveTypeParameterDistinct(type1, boundClass2);
+    }
+
+    return !boundClass1.isInheritor(boundClass2, true) && !boundClass2.isInheritor(boundClass1, true);
+  }
+
+  public static boolean try2ProveTypeParameterDistinct(PsiType type, PsiClass typeParameter) {
+    final PsiClassType[] types = typeParameter.getExtendsListTypes();
+    if (types.length == 0) return false;
+    return provablyDistinct(PsiWildcardType.createExtends(typeParameter.getManager(), types[0]), type);
+  }
+}
index 41dfb275a916945d756b48bc9c3bcc9948697309..beda5df2de3a7eb0f3402985d1ab1c7baa75349c 100644 (file)
@@ -30,7 +30,6 @@ import org.jetbrains.annotations.Nullable;
  * @see PsiParser
  * @see ASTNode
  */
-
 public interface PsiBuilder extends UserDataHolder {
   /**
    * Returns the complete text being parsed.
@@ -46,8 +45,9 @@ public interface PsiBuilder extends UserDataHolder {
 
   /**
    * Returns the type of current token from the lexer.
-   * @see #setTokenTypeRemapper(ITokenTypeRemapper).
+   *
    * @return the token type, or null when lexing is over.
+   * @see #setTokenTypeRemapper(ITokenTypeRemapper).
    */
   @Nullable
   IElementType getTokenType();
@@ -55,6 +55,7 @@ public interface PsiBuilder extends UserDataHolder {
   /**
    * Sets optional remapper that can change the type of freshly lexed tokens.
    * Output of getTokenType() is affected by it.
+   *
    * @param remapper the remapper object, or null.
    */
   void setTokenTypeRemapper(ITokenTypeRemapper remapper);
@@ -123,7 +124,7 @@ public interface PsiBuilder extends UserDataHolder {
      * before specified one. All markers added between start of this marker and the marker specified as end one
      * must be either dropped or completed.
      *
-     * @param type the type of the node in the AST tree.
+     * @param type   the type of the node in the AST tree.
      * @param before marker to complete this one before.
      */
     void doneBefore(IElementType type, Marker before);
@@ -132,8 +133,8 @@ public interface PsiBuilder extends UserDataHolder {
      * Like {@linkplain #doneBefore(IElementType, Marker)}, but in addition an error element with given text
      * is inserted right before this marker's end.
      *
-     * @param type the type of the node in the AST tree.
-     * @param before marker to complete this one before.
+     * @param type         the type of the node in the AST tree.
+     * @param before       marker to complete this one before.
      * @param errorMessage for error element.
      */
     void doneBefore(IElementType type, Marker before, String errorMessage);
@@ -150,9 +151,19 @@ public interface PsiBuilder extends UserDataHolder {
      * Like {@linkplain #error(String)}, but the marker is completed before specified one.
      *
      * @param message for error element.
-     * @param before marker to complete this one before.
+     * @param before  marker to complete this one before.
      */
     void errorBefore(String message, Marker before);
+
+    /**
+     * Allows to define custom edge processors instead of default ones. If any of parameters is null
+     * then corresponding processor won't be changed (keeping previously set or default processor).
+     * It is an error to set right processor for not-done marker.
+     *
+     * @param left  new left edge processor.
+     * @param right new right edge processor.
+     */
+    void setCustomEdgeProcessors(WhitespacesAndCommentsProcessor left, WhitespacesAndCommentsProcessor right);
   }
 
   /**
@@ -185,7 +196,9 @@ public interface PsiBuilder extends UserDataHolder {
   ASTNode getTreeBuilt();
 
   /**
-   * Same as {@link #getTreeBuilt()} but returns a light tree, which is build faster, produces less garbage but is incapable of creating a PSI over.
+   * Same as {@link #getTreeBuilt()} but returns a light tree, which is build faster,
+   * produces less garbage but is incapable of creating a PSI over.
+   *
    * @return the light tree built.
    */
   FlyweightCapableTreeStructure<LighterASTNode> getLightTree();
@@ -201,7 +214,8 @@ public interface PsiBuilder extends UserDataHolder {
   void enforceCommentTokens(TokenSet tokens);
 
   /**
-   * @return latest left done node for context dependent parsing 
+   * @return latest left done node for context dependent parsing.
    */
-  @Nullable LighterASTNode getLatestDoneMarker();
+  @Nullable
+  LighterASTNode getLatestDoneMarker();
 }
diff --git a/platform/lang-api/src/com/intellij/lang/WhitespacesAndCommentsProcessor.java b/platform/lang-api/src/com/intellij/lang/WhitespacesAndCommentsProcessor.java
new file mode 100644 (file)
index 0000000..31a79b7
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2010 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.lang;
+
+import com.intellij.psi.tree.IElementType;
+
+import java.util.List;
+
+/**
+ * Interface for defining custom element's edge processors for {@linkplain com.intellij.lang.PsiBuilder PSI builder}.
+ * Each element has a pair of edge processors: for it's left and right edge. Edge processors defines position
+ * of element start and end in token stream with recognition of whitespace and comment tokens surrounding the element.
+ *
+ * @see com.intellij.lang.PsiBuilder.Marker#setCustomEdgeProcessors(WhitespacesAndCommentsProcessor, WhitespacesAndCommentsProcessor)
+ */
+public interface WhitespacesAndCommentsProcessor {
+  /**
+   * <p>Analyzes whitespace and comment tokens at element's edge and returns element's edge position relative to these tokens.
+   * Value returned by left edge processor will be used as a pointer to a first token of element.
+   * Value returned by right edge processor will be used as a pointer to a token next of element's last token.
+   * <p/>
+   * <p>Example 1: if a processor for left edge wants to leave all whitespaces and comments out of element's scope
+   * (before it's start) it should return value of <code>tokens.size()</code> placing element's start pointer to a first
+   * token after series of whitespaces/comments.
+   * <p/>
+   * <p>Example 2: if a processor for right edge wants to leave all whitespaces and comments out of element's scope
+   * (after it's end) it should return value of <code>0</code> placing element's end pointer to a first
+   * whitespace or comment after element's end.
+   *
+   * @param tokens sequence of whitespace and comment tokens at the element's edge.
+   * @return position of element's edge relative to given tokens
+   */
+  int process(List<IElementType> tokens);
+}
index 48648543f6dcff51fe84a275899f8d9fcaf99b5a..0ac05c043156ec664bcc7527206d37d3faa24b99 100644 (file)
@@ -88,6 +88,19 @@ public class PsiTreeUtil {
     }
   }
 
+  @Nullable
+  public static PsiElement findCommonParent(@NotNull List<? extends PsiElement> elements) {
+    if (elements.isEmpty())  return null;
+    PsiElement toReturn = null;
+    for (PsiElement element : elements) {
+      if (element == null) continue;
+      toReturn = toReturn == null ? element : findCommonParent(toReturn, element);
+      if (toReturn == null) return null;
+    }
+
+    return toReturn;
+  }
+
   @Nullable
   public static PsiElement findCommonParent(@NotNull PsiElement... elements) {
     if (elements.length == 0)  return null;
@@ -288,6 +301,20 @@ public class PsiTreeUtil {
     return null;
   }
 
+  @Nullable
+  public static <T extends PsiElement> T getTopmostParentOfType(@Nullable PsiElement element, @NotNull Class<T> aClass) {
+    T answer = getParentOfType(element, aClass);
+
+    do {
+      T next = getParentOfType(answer, aClass);
+      if (next == null) break;
+      answer = next;
+    }
+    while (true);
+
+    return answer;
+  }
+
   @Nullable public static <T extends PsiElement> T getParentOfType(@Nullable PsiElement element, @NotNull Class<T> aClass) {
     return getParentOfType(element, aClass, true);
   }
index 5f8f2360b1c2c1601faee10395218b722f1285e8..0fe6685ad12c71c06c3d5edc6ebf0098b25ba61f 100644 (file)
@@ -19,7 +19,6 @@ package com.intellij.codeInsight.editorActions;
 import com.intellij.codeInsight.CodeInsightBundle;
 import com.intellij.codeInsight.CodeInsightSettings;
 import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegate;
-import com.intellij.injected.editor.DocumentWindow;
 import com.intellij.lang.*;
 import com.intellij.lang.documentation.CodeDocumentationProvider;
 import com.intellij.lang.documentation.CompositeDocumentationProvider;
@@ -40,7 +39,6 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
 import com.intellij.psi.codeStyle.CodeStyleSettings;
 import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
 import com.intellij.psi.impl.source.PostprocessReformattingAspect;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtilBase;
@@ -326,15 +324,7 @@ public class EnterHandler extends BaseEnterHandler {
         if (CodeInsightSettings.getInstance().SMART_INDENT_ON_ENTER || myForceIndent || docStart || docAsterisk ||
             slashSlash) {
           final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(getProject());
-          if (myDocument instanceof DocumentWindow) {
-            DocumentWindow documentWindow = (DocumentWindow)myDocument;
-            final int correctedOffset = codeStyleManager.adjustLineIndent(InjectedLanguageUtil.getTopLevelFile(myFile),
-                                                                          documentWindow.injectedToHost(myOffset));
-            myOffset = documentWindow.hostToInjected(correctedOffset);
-          }
-          else {
-            myOffset = codeStyleManager.adjustLineIndent(myFile, myOffset);
-          }
+          myOffset = codeStyleManager.adjustLineIndent(myFile, myOffset);
         }
 
         if (docAsterisk || docStart || slashSlash) {
index 581897d7d7bad29b2394df815ca57abd6fa3d419..1863a891d053014c89c2d8b47bbc8e8744259116 100644 (file)
@@ -17,7 +17,6 @@
 package com.intellij.codeInsight.generation;
 
 import com.intellij.codeInsight.CodeInsightActionHandler;
-import com.intellij.injected.editor.DocumentWindow;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.*;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -26,7 +25,6 @@ import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.PsiDocumentManager;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NotNull;
 
@@ -56,17 +54,7 @@ public class AutoIndentLinesHandler implements CodeInsightActionHandler {
     int col = editor.getCaretModel().getLogicalPosition().column;
 
     try{
-      if (document instanceof DocumentWindow) {
-        final DocumentWindow documentWindow = (DocumentWindow)document;
-        int hostLine = documentWindow.injectedToHostLine(line1);
-        int hostStartOffset = documentWindow.injectedToHost(startOffset);
-        int hostEndOffset = documentWindow.injectedToHost(endOffset);
-        adjustLineIndent(InjectedLanguageUtil.getTopLevelFile(file), documentWindow.getDelegate(),
-                         hostStartOffset, hostEndOffset, hostLine, project);
-      }
-      else {
-        adjustLineIndent(file, document, startOffset, endOffset, line1, project);
-      }
+      adjustLineIndent(file, document, startOffset, endOffset, line1, project);
     }
     catch(IncorrectOperationException e){
       LOG.error(e);
@@ -92,10 +80,10 @@ public class AutoIndentLinesHandler implements CodeInsightActionHandler {
 
   private static void adjustLineIndent(PsiFile file,
                                 Document document,
-                                int startOffset, int endOffset, int line1, Project project) {
+                                int startOffset, int endOffset, int line, Project project) {
     CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
     if (startOffset == endOffset) {
-      int lineStart = document.getLineStartOffset(line1);
+      int lineStart = document.getLineStartOffset(line);
       if (codeStyleManager.isLineToBeIndented(file, lineStart)) {
         codeStyleManager.adjustLineIndent(file, lineStart);
       }
index 40a6b22d50534e4ee8af9bc91055717c7f1bbb0a..e264cb8be62a13ebbd990d237a7a2409abe03bda 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.codeInsight.template;
 
+import com.intellij.codeInsight.template.impl.TemplateContext;
 import com.intellij.codeInsight.template.impl.TemplateImpl;
 import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
 import com.intellij.codeInsight.template.impl.TemplateSettings;
@@ -75,24 +76,31 @@ public class CustomTemplateCallback {
   }
 
   @Nullable
-  public TemplateImpl findApplicableTemplate(@NotNull String key) {
-    List<TemplateImpl> templates = findApplicableTemplates(key);
+  public TemplateImpl findApplicableTemplate(@NotNull String key, TemplateContextType... contextTypes) {
+    List<TemplateImpl> templates = findApplicableTemplates(key, contextTypes);
     return templates.size() > 0 ? templates.get(0) : null;
   }
 
   @NotNull
-  public List<TemplateImpl> findApplicableTemplates(String key) {
+  public List<TemplateImpl> findApplicableTemplates(String key, TemplateContextType... contextTypes) {
     List<TemplateImpl> templates = getMatchingTemplates(key);
-    templates = filterApplicableCandidates(templates);
+    templates = filterApplicableCandidates(templates, contextTypes);
     return templates;
   }
 
-  private List<TemplateImpl> filterApplicableCandidates(Collection<TemplateImpl> candidates) {
+  private List<TemplateImpl> filterApplicableCandidates(Collection<TemplateImpl> candidates, TemplateContextType... contextTypes) {
     List<TemplateImpl> result = new ArrayList<TemplateImpl>();
     for (TemplateImpl candidate : candidates) {
       if (TemplateManagerImpl.isApplicable(myFile, myOffset, candidate)) {
         result.add(candidate);
       }
+      TemplateContext context = candidate.getTemplateContext();
+      for (TemplateContextType contextType : contextTypes) {
+        if (context.isEnabled(contextType)) {
+          result.add(candidate);
+          break;
+        }
+      }
     }
     return result;
   }
index fdd1a50e1a88580cdfeb564d70ff3ed567eec6b1..3b8aa413476f03b98b56c10438bc4c6ccea430f5 100644 (file)
@@ -23,7 +23,10 @@ import com.intellij.openapi.application.ex.DecodeDefaultsUtil;
 import com.intellij.openapi.components.*;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.options.*;
+import com.intellij.openapi.options.BaseSchemeProcessor;
+import com.intellij.openapi.options.SchemeProcessor;
+import com.intellij.openapi.options.SchemesManager;
+import com.intellij.openapi.options.SchemesManagerFactory;
 import com.intellij.openapi.util.InvalidDataException;
 import com.intellij.openapi.util.JDOMUtil;
 import com.intellij.openapi.util.WriteExternalException;
@@ -530,6 +533,7 @@ public class TemplateSettings implements PersistentStateComponent<Element>, Expo
         clearPreviouslyRegistered(template);
         addTemplateImpl(template);
       }
+      addTemplateById(template);
 
       result.addElement(template);
     }
@@ -591,20 +595,7 @@ public class TemplateSettings implements PersistentStateComponent<Element>, Expo
   }
 
   public void readHiddenTemplateFile(Document document) throws InvalidDataException {
-    if (document == null) {
-      throw new InvalidDataException();
-    }
-    Element root = document.getRootElement();
-    if (root == null || !TEMPLATE_SET.equals(root.getName())) {
-      throw new InvalidDataException();
-    }
-
-    for (final Object o1 : root.getChildren(TEMPLATE)) {
-
-      addTemplateById(readTemplateFromElement(false, null, (Element)o1, getClass().getClassLoader()));
-    }
-
-
+    readTemplateFile(document, null, false, false, getClass().getClassLoader());
   }
 
   private static void saveTemplate(TemplateImpl template, Element templateSetElement) {
index 1e40a8720fe137795e3d90ff4d451a009162d68d..6040e715806dea007890c5fe36c96c88f5ebd577 100644 (file)
@@ -62,7 +62,7 @@ public class ProgramRunnerUtil {
       }
 
       while (!RunManagerImpl.canRunConfiguration(configuration, executor)) {
-        if (0 == Messages.showOkCancelDialog(project, "Configuration is still wrong. Do you want to edit it again?", "Change configuration settings", Messages.getErrorIcon())) {
+        if (0 == Messages.showYesNoDialog(project, "Configuration is still wrong. Do you want to edit it again?", "Change configuration settings", Messages.getErrorIcon())) {
           final boolean result2 = RunDialog.editConfiguration(project, configuration, "Edit configuration", executor.getActionName(), executor.getIcon());
           if (!result2) {
             return;
index 56f009b94c4a3d50c5de55d117f1a81e50785304..8c6f7154cf60bea01abb2c8840e02b24fac71eec 100644 (file)
@@ -137,6 +137,11 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
     return text.toString();
   }
 
+  @Override
+  public String getText(TextRange range) {
+    return range.substring(getText());
+  }
+
   @NotNull
   public CharSequence getCharsSequence() {
     return getText();
index 7cb9ad66da4fdadb388466beddbb76c33140899e..3f0d6f04386b57a9c191b49d8bd52983b57a9bfa 100644 (file)
@@ -40,9 +40,7 @@ import com.intellij.psi.tree.*;
 import com.intellij.util.CharTable;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.ThreeState;
-import com.intellij.util.containers.Convertor;
-import com.intellij.util.containers.LimitedPool;
-import com.intellij.util.containers.Stack;
+import com.intellij.util.containers.*;
 import com.intellij.util.diff.DiffTree;
 import com.intellij.util.diff.DiffTreeChangeBuilder;
 import com.intellij.util.diff.FlyweightCapableTreeStructure;
@@ -55,6 +53,7 @@ import org.jetbrains.annotations.TestOnly;
 
 import java.lang.reflect.Field;
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * User: max
@@ -104,6 +103,18 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
     }
   });
 
+  private static final WhitespacesAndCommentsProcessor DEFAULT_LEFT_EDGE_PROCESSOR = new WhitespacesAndCommentsProcessor() {
+    public int process(final List<IElementType> tokens) {
+      return tokens.size();
+    }
+  };
+
+  private static final WhitespacesAndCommentsProcessor DEFAULT_RIGHT_EDGE_PROCESSOR = new WhitespacesAndCommentsProcessor() {
+    public int process(final List<IElementType> tokens) {
+      return 0;
+    }
+  };
+
   @NonNls private static final String UNBALANCED_MESSAGE =
     "Unbalanced tree. Most probably caused by unbalanced markers. Try calling setDebugMode(true) against PsiBuilder passed to identify exact location of the problem";
 
@@ -189,6 +200,17 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
     public abstract int hc();
   }
 
+  private abstract static class ProductionMarker extends Node {
+    public int myLexemeIndex;
+    public WhitespacesAndCommentsProcessor myEdgeProcessor;
+    ProductionMarker next;
+
+    public void clean() {
+      myLexemeIndex = 0;
+      next = null;
+    }
+  }
+
   private static class StartMarker extends ProductionMarker implements Marker {
     public PsiBuilderImpl myBuilder;
     public IElementType myType;
@@ -198,6 +220,10 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
     public ProductionMarker lastChild;
     private int myHC = -1;
 
+    private StartMarker() {
+      myEdgeProcessor = DEFAULT_LEFT_EDGE_PROCESSOR;
+    }
+
     public void clean() {
       super.clean();
       myBuilder = null;
@@ -207,6 +233,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
       firstChild = null;
       lastChild = null;
       myHC = -1;
+      myEdgeProcessor = DEFAULT_LEFT_EDGE_PROCESSOR;
     }
 
     public int hc() {
@@ -306,6 +333,17 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
     public IElementType getTokenType() {
       return myType;
     }
+
+    public void setCustomEdgeProcessors(final WhitespacesAndCommentsProcessor left, final WhitespacesAndCommentsProcessor right) {
+      if (left != null) {
+        myEdgeProcessor = left;
+      }
+
+      if (right != null) {
+        if (myDoneMarker == null) throw new IllegalArgumentException("Cannot set right-edge processor for unclosed marker");
+        myDoneMarker.myEdgeProcessor = right;
+      }
+    }
   }
 
   private Marker precede(final StartMarker marker) {
@@ -371,28 +409,26 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
     }
   }
 
-  private abstract static class ProductionMarker extends Node {
-    public int myLexemeIndex;
-    ProductionMarker next;
-
-    public void clean() {
-      myLexemeIndex = 0;
-      next = null;
-    }
-  }
-
   private static class DoneMarker extends ProductionMarker {
     public StartMarker myStart;
     public boolean myCollapse = false;
-    public boolean myTieToTheLeft = false;
 
-    public DoneMarker() {}
+    public DoneMarker() {
+      myEdgeProcessor = DEFAULT_RIGHT_EDGE_PROCESSOR;
+    }
 
-    public DoneMarker(final StartMarker marker, int currentLexeme) {
+    public DoneMarker(final StartMarker marker, final int currentLexeme) {
+      this();
       myLexemeIndex = currentLexeme;
       myStart = marker;
     }
 
+    public void clean() {
+      super.clean();
+      myStart = null;
+      myEdgeProcessor = DEFAULT_RIGHT_EDGE_PROCESSOR;
+    }
+
     public int hc() {
       throw new UnsupportedOperationException("Shall not be called on this kind of markers");
     }
@@ -408,17 +444,12 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
     public int getStartOffset() {
       throw new UnsupportedOperationException("Shall not be called on this kind of markers");
     }
-
-    public void clean() {
-      super.clean();
-      myStart = null;
-    }
   }
 
   private static class DoneWithErrorMarker extends DoneMarker {
     public String myMessage;
 
-    public DoneWithErrorMarker(final StartMarker marker, int currentLexeme, String message) {
+    public DoneWithErrorMarker(final StartMarker marker, final int currentLexeme, final String message) {
       super(marker, currentLexeme);
       myMessage = message;
     }
@@ -437,6 +468,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
       myBuilder = builder;
       myLexemeIndex = idx;
       myMessage = message;
+      myEdgeProcessor = DEFAULT_RIGHT_EDGE_PROCESSOR;
     }
 
     public int hc() {
@@ -581,7 +613,8 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
     doValidityChecks(marker, null);
 
     DoneWithErrorMarker doneMarker = new DoneWithErrorMarker((StartMarker)marker, myCurrentLexeme, message);
-    doneMarker.myTieToTheLeft = isEmpty(((StartMarker)marker).myLexemeIndex, myCurrentLexeme);
+    boolean tieToTheLeft = isEmpty(((StartMarker)marker).myLexemeIndex, myCurrentLexeme);
+    if (tieToTheLeft) ((StartMarker)marker).myEdgeProcessor = DEFAULT_RIGHT_EDGE_PROCESSOR;
 
     ((StartMarker)marker).myDoneMarker = doneMarker;
     myProduction.add(doneMarker);
@@ -594,7 +627,8 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
     int beforeIndex = myProduction.lastIndexOf(before);
 
     DoneWithErrorMarker doneMarker = new DoneWithErrorMarker((StartMarker)marker, ((StartMarker)before).myLexemeIndex, message);
-    doneMarker.myTieToTheLeft = isEmpty(((StartMarker)marker).myLexemeIndex, ((StartMarker)before).myLexemeIndex);
+    boolean tieToTheLeft = isEmpty(((StartMarker)marker).myLexemeIndex, ((StartMarker)before).myLexemeIndex);
+    if (tieToTheLeft) ((StartMarker)marker).myEdgeProcessor = DEFAULT_RIGHT_EDGE_PROCESSOR;
 
     ((StartMarker)marker).myDoneMarker = doneMarker;
     myProduction.add(beforeIndex, doneMarker);
@@ -606,8 +640,9 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
     DoneMarker doneMarker = DONE_MARKERS.alloc();
     doneMarker.myStart = (StartMarker)marker;
     doneMarker.myLexemeIndex = myCurrentLexeme;
-    doneMarker.myTieToTheLeft = doneMarker.myStart.myType.isLeftBound() &&
-                                isEmpty(((StartMarker)marker).myLexemeIndex, myCurrentLexeme);
+    boolean tieToTheLeft = doneMarker.myStart.myType.isLeftBound() &&
+                           isEmpty(((StartMarker)marker).myLexemeIndex, myCurrentLexeme);
+    if (tieToTheLeft) ((StartMarker)marker).myEdgeProcessor = DEFAULT_RIGHT_EDGE_PROCESSOR;
 
     ((StartMarker)marker).myDoneMarker = doneMarker;
     myProduction.add(doneMarker);
@@ -622,8 +657,9 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
     DoneMarker doneMarker = DONE_MARKERS.alloc();
     doneMarker.myLexemeIndex = ((StartMarker)before).myLexemeIndex;
     doneMarker.myStart = (StartMarker)marker;
-    doneMarker.myTieToTheLeft = doneMarker.myStart.myType.isLeftBound() &&
-                                isEmpty(((StartMarker)marker).myLexemeIndex, ((StartMarker)before).myLexemeIndex);
+    boolean tieToTheLeft = doneMarker.myStart.myType.isLeftBound() &&
+                           isEmpty(((StartMarker)marker).myLexemeIndex, ((StartMarker)before).myLexemeIndex);
+    if (tieToTheLeft) ((StartMarker)marker).myEdgeProcessor = DEFAULT_RIGHT_EDGE_PROCESSOR;
 
     ((StartMarker)marker).myDoneMarker = doneMarker;
     myProduction.add(beforeIndex, doneMarker);
@@ -789,49 +825,33 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
   private StartMarker prepareLightTree() {
     markTokenTypeChecked();
 
-    final MyList fProduction = myProduction;
-    StartMarker rootMarker = (StartMarker)fProduction.get(0);
-
-    for (int i = 1; i < fProduction.size() - 1; i++) {
-      ProductionMarker item = fProduction.get(i);
+    for (int i = 1; i < myProduction.size() - 1; i++) {
+      final ProductionMarker item = myProduction.get(i);
 
       if (item instanceof StartMarker && ((StartMarker)item).myDoneMarker == null) {
         LOG.error(UNBALANCED_MESSAGE);
       }
 
-      if (item instanceof StartMarker && ((StartMarker)item).myDoneMarker.myTieToTheLeft) {
-        int prevProductionLexIndex = fProduction.get(i - 1).myLexemeIndex;
-        while (item.myLexemeIndex > prevProductionLexIndex &&
-               item.myLexemeIndex - 1 < myLexemeCount &&
-               whitespaceOrComment(myLexTypes[item.myLexemeIndex - 1])) {
-          item.myLexemeIndex--;
-        }
-        ((StartMarker)item).myDoneMarker.myLexemeIndex = item.myLexemeIndex;
-      }
-      else if (item instanceof StartMarker) {
-        while (item.myLexemeIndex < myLexemeCount &&
-               whitespaceOrComment(myLexTypes[item.myLexemeIndex])) {
-          item.myLexemeIndex++;
-        }
-      }
-      else if (item instanceof DoneMarker || item instanceof ErrorItem) {
-        int prevProductionLexIndex = fProduction.get(i - 1).myLexemeIndex;
-        while (item.myLexemeIndex > prevProductionLexIndex &&
-               item.myLexemeIndex - 1 < myLexemeCount &&
-               whitespaceOrComment(myLexTypes[item.myLexemeIndex - 1])) {
-          item.myLexemeIndex--;
-        }
-      }
+      final int prevProductionLexIndex = myProduction.get(i - 1).myLexemeIndex;
+      int wsStartIndex = item.myLexemeIndex;
+      while (wsStartIndex > prevProductionLexIndex && whitespaceOrComment(myLexTypes[wsStartIndex - 1])) wsStartIndex--;
+
+      int wsEndIndex = item.myLexemeIndex;
+      while (wsEndIndex < myLexemeCount && whitespaceOrComment(myLexTypes[wsEndIndex])) wsEndIndex++;
+
+      final List<IElementType> wsTokens = CollectionFactory.arrayList(myLexTypes, wsStartIndex, wsEndIndex);
+      item.myLexemeIndex = wsStartIndex + item.myEdgeProcessor.process(wsTokens);
     }
 
+    StartMarker rootMarker = (StartMarker)myProduction.get(0);
     StartMarker curNode = rootMarker;
 
     Stack<StartMarker> nodes = new Stack<StartMarker>();
     nodes.push(rootMarker);
 
     int lastErrorIndex = -1;
-    for (int i = 1; i < fProduction.size(); i++) {
-      ProductionMarker item = fProduction.get(i);
+    for (int i = 1; i < myProduction.size(); i++) {
+      ProductionMarker item = myProduction.get(i);
 
       if (curNode == null) LOG.error("Unexpected end of the production");
 
index 975199019bc19601969087a7a1a7d2c74cd2a73c..3f2bef65b39d62184c4ca0532bcee1535e64f28a 100644 (file)
@@ -153,6 +153,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
             }
           }
           profile.readExternal(rootElement);
+          profile.setLocal(true);
           profile.initInspectionTools();
           if (myProfileManager.getProfile(profile.getName(), false) != null) {
             if (Messages.showOkCancelDialog(myWholePanel, "Profile with name \'" + profile.getName() + "\' already exists. Do you want to overwrite it?", "Warning", Messages.getInformationIcon()) != DialogWrapper.OK_EXIT_CODE) return;
index 680375f7ec854e5a975eb56bb7d54b4ae9d9b6db..883f8a48c311bc1b113e9e6233f2e57b91743d02 100644 (file)
@@ -26,7 +26,6 @@ import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.RangeMarker;
-import com.intellij.openapi.fileTypes.FileType;
 import com.intellij.openapi.fileTypes.FileTypeManager;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
@@ -559,9 +558,7 @@ public class PostprocessReformattingAspect implements PomModelAspect, Disposable
     final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(myPsiManager.getProject());
     final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myPsiManager.getProject());
     final Document document = viewProvider.getDocument();
-    final FileType fileType = viewProvider.getVirtualFile().getFileType();
-    final Helper helper = HelperFactory.createHelper(fileType, myPsiManager.getProject());
-    final CodeFormatterFacade codeFormatter = new CodeFormatterFacade(styleSettings, helper);
+    final CodeFormatterFacade codeFormatter = new CodeFormatterFacade(styleSettings);
 
     documentManager.commitDocument(document);
     return codeFormatter;
index 8349d2e3792deeb47a1fc40dafc7f6ae783d6b6e..c2b4d44636ff9b588c511ebea9b4a459ab11271c 100644 (file)
 package com.intellij.psi.impl.source.codeStyle;
 
 import com.intellij.formatting.*;
+import com.intellij.injected.editor.DocumentWindow;
 import com.intellij.lang.ASTNode;
 import com.intellij.lang.LanguageFormatting;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.RangeMarker;
 import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.fileTypes.FileType;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.JDOMUtil;
 import com.intellij.openapi.util.TextRange;
@@ -34,6 +34,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
 import com.intellij.psi.formatter.DocumentBasedFormattingModel;
 import com.intellij.psi.impl.source.PostprocessReformattingAspect;
 import com.intellij.psi.impl.source.SourceTreeToPsiMap;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.util.IncorrectOperationException;
 
@@ -41,50 +42,45 @@ public class CodeFormatterFacade {
   private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade");
 
   private final CodeStyleSettings mySettings;
-  private final Helper myHelper;
 
-  public CodeFormatterFacade(CodeStyleSettings settings, Helper helper) {
+  public CodeFormatterFacade(CodeStyleSettings settings) {
     mySettings = settings;
-    myHelper = helper;
   }
 
-  public ASTNode process(ASTNode element, int parent_indent) {
-    final PsiFile file = SourceTreeToPsiMap.treeElementToPsi(element).getContainingFile();
-    final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
-    if (builder != null) {
-      TextRange range = element.getTextRange();
-      return processRange(element, range.getStartOffset(), range.getEndOffset());
-    }
-
-    return element;
+  public ASTNode processElement(ASTNode element) {
+    TextRange range = element.getTextRange();
+    return processRange(element, range.getStartOffset(), range.getEndOffset());
   }
 
   public ASTNode processRange(final ASTNode element, final int startOffset, final int endOffset) {
-    final FileType fileType = myHelper.getFileType();
-
     final PsiElement psiElement = SourceTreeToPsiMap.treeElementToPsi(element);
-    final PsiFile file = SourceTreeToPsiMap.treeElementToPsi(element).getContainingFile();
-    final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
+    final PsiFile file = psiElement.getContainingFile();
     final Document document = file.getViewProvider().getDocument();
     final RangeMarker rangeMarker = document != null && endOffset < document.getTextLength()? document.createRangeMarker(startOffset, endOffset):null;
 
+    PsiElement elementToFormat = document instanceof DocumentWindow ? InjectedLanguageUtil.getTopLevelFile(file) : psiElement;
+    final PsiFile fileToFormat = elementToFormat.getContainingFile();
+
+    final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(fileToFormat);
     if (builder != null) {
       TextRange range = preprocess(element, startOffset, endOffset);
+      if (document instanceof DocumentWindow) {
+        DocumentWindow documentWindow = (DocumentWindow)document;
+        range = new TextRange(documentWindow.injectedToHost(range.getStartOffset()), documentWindow.injectedToHost(range.getEndOffset()));
+      }
+
       //final SmartPsiElementPointer pointer = SmartPointerManager.getInstance(psiElement.getProject()).createSmartPsiElementPointer(psiElement);
-      final PsiFile containingFile = psiElement.getContainingFile();
-      final FormattingModel model = builder.createModel(psiElement, mySettings);
-      if (containingFile.getTextLength() > 0) {
+      final FormattingModel model = builder.createModel(elementToFormat, mySettings);
+      if (file.getTextLength() > 0) {
         try {
           FormatterEx.getInstanceEx().format(model, mySettings,
-                                             mySettings.getIndentOptions(fileType), new FormatTextRanges(range, true));
+                                             mySettings.getIndentOptions(fileToFormat.getFileType()), new FormatTextRanges(range, true));
         }
         catch (IncorrectOperationException e) {
           LOG.error(e);
         }
       }
 
-      /*
-       */
       if (!psiElement.isValid()) {
         if (rangeMarker != null) {
           final PsiElement at = file.findElementAt(rangeMarker.getStartOffset());
@@ -104,8 +100,6 @@ public class CodeFormatterFacade {
   }
 
   public void processTextWithPostponedFormatting(final PsiFile file, final FormatTextRanges ranges) {
-    final FileType fileType = myHelper.getFileType();
-
     final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
 
     if (builder != null) {
@@ -118,11 +112,11 @@ public class CodeFormatterFacade {
           Project project = file.getProject();
           final FormattingModel model = new DocumentBasedFormattingModel(rootBlock,
                                                                          PsiDocumentManager.getInstance(project).getDocument(file),
-                                                                         project, mySettings, fileType, file);
+                                                                         project, mySettings, file.getFileType(), file);
 
           //printToConsole(rootBlock, model);
 
-          FormatterEx.getInstanceEx().format(model, mySettings, mySettings.getIndentOptions(fileType), ranges);
+          FormatterEx.getInstanceEx().format(model, mySettings, mySettings.getIndentOptions(file.getFileType()), ranges);
         }
         catch (IncorrectOperationException e) {
           LOG.error(e);
@@ -139,7 +133,6 @@ public class CodeFormatterFacade {
   }
 
   public void processText(final PsiFile file, final FormatTextRanges ranges) {
-    final FileType fileType = myHelper.getFileType();
 
     final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
 
@@ -151,9 +144,9 @@ public class CodeFormatterFacade {
           Project project = file.getProject();
           final FormattingModel model = new DocumentBasedFormattingModel(originalModel.getRootBlock(),
             PsiDocumentManager.getInstance(project).getDocument(file),
-            project, mySettings, fileType, file);
+            project, mySettings, file.getFileType(), file);
 
-          FormatterEx.getInstanceEx().format(model, mySettings, mySettings.getIndentOptions(fileType), ranges);
+          FormatterEx.getInstanceEx().format(model, mySettings, mySettings.getIndentOptions(file.getFileType()), ranges);
         }
         catch (IncorrectOperationException e) {
           LOG.error(e);
index 5a99c90b50ea5294c2d6ad010d70be341aaa9ef1..4f36eef38921c0b5e9e1036757f948b75fe2b612 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.formatting.FormatTextRanges;
 import com.intellij.formatting.FormatterEx;
 import com.intellij.formatting.FormattingModel;
 import com.intellij.formatting.FormattingModelBuilder;
+import com.intellij.injected.editor.DocumentWindow;
 import com.intellij.lang.*;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
@@ -27,24 +28,19 @@ import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.StdFileTypes;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.CodeStyleManager;
 import com.intellij.psi.codeStyle.CodeStyleSettings;
 import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
 import com.intellij.psi.codeStyle.Indent;
-import com.intellij.psi.formatter.DocumentBasedFormattingModel;
 import com.intellij.psi.impl.CheckUtil;
 import com.intellij.psi.impl.source.PostprocessReformattingAspect;
-import com.intellij.psi.impl.source.PsiFileImpl;
 import com.intellij.psi.impl.source.SourceTreeToPsiMap;
 import com.intellij.psi.impl.source.tree.*;
 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
-import com.intellij.psi.util.PsiUtilBase;
 import com.intellij.util.CharTable;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.text.CharArrayUtil;
@@ -80,14 +76,7 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
     }
 
     ASTNode treeElement = SourceTreeToPsiMap.psiElementToTree(element);
-    PsiFileImpl file = (PsiFileImpl)element.getContainingFile();
-    FileType fileType = StdFileTypes.JAVA;
-    if (file != null) {
-      fileType = file.getFileType();
-    }
-    Helper helper = HelperFactory.createHelper(fileType, myProject);
-    final PsiElement formatted = SourceTreeToPsiMap.treeElementToPsi(
-      new CodeFormatterFacade(getSettings(), helper).process(treeElement, -1));
+    final PsiElement formatted = SourceTreeToPsiMap.treeElementToPsi(new CodeFormatterFacade(getSettings()).processElement(treeElement));
     if (!canChangeWhiteSpacesOnly) {
       return postProcessElement(formatted);
     } else {
@@ -135,6 +124,15 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
     ApplicationManager.getApplication().assertWriteAccessAllowed();
     PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
 
+    final Project project = file.getProject();
+    final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
+    if (document instanceof DocumentWindow) {
+      file = InjectedLanguageUtil.getTopLevelFile(file);
+      final DocumentWindow documentWindow = (DocumentWindow)document;
+      startOffset = documentWindow.injectedToHost(startOffset);
+      endOffset = documentWindow.injectedToHost(endOffset);
+    }
+
     CheckUtil.checkWritable(file);
     if (!SourceTreeToPsiMap.hasTreeElement(file)) {
       return;
@@ -143,9 +141,7 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
     ASTNode treeElement = SourceTreeToPsiMap.psiElementToTree(file);
     transformAllChildren(treeElement);
 
-    FileType fileType = file.getFileType();
-    Helper helper = HelperFactory.createHelper(fileType, myProject);
-    final CodeFormatterFacade codeFormatter = new CodeFormatterFacade(getSettings(), helper);
+    final CodeFormatterFacade codeFormatter = new CodeFormatterFacade(getSettings());
     LOG.assertTrue(file.isValid());
     final PsiElement start = findElementInTreeWithFormatterEnabled(file, startOffset);
     final PsiElement end = findElementInTreeWithFormatterEnabled(file, endOffset);
@@ -186,13 +182,7 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
     }
 
     ASTNode treeElement = SourceTreeToPsiMap.psiElementToTree(element);
-    FileType fileType = StdFileTypes.JAVA;
-    PsiFile file = element.getContainingFile();
-    if (file != null) {
-      fileType = file.getFileType();
-    }
-    Helper helper = HelperFactory.createHelper(fileType, myProject);
-    final CodeFormatterFacade codeFormatter = new CodeFormatterFacade(getSettings(), helper);
+    final CodeFormatterFacade codeFormatter = new CodeFormatterFacade(getSettings());
     final PsiElement formatted = SourceTreeToPsiMap.treeElementToPsi(codeFormatter.processRange(treeElement, startOffset, endOffset));
 
     return canChangeWhiteSpacesOnly ? formatted : postProcessElement(formatted);
@@ -221,66 +211,15 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
   }
 
   public int adjustLineIndent(@NotNull final PsiFile file, final int offset) throws IncorrectOperationException {
-    final Computable<Pair<Integer, IncorrectOperationException>> computable = new Computable<Pair<Integer, IncorrectOperationException>>() {
-      public Pair<Integer, IncorrectOperationException> compute() {
-        try {
-          return new Pair<Integer, IncorrectOperationException>(adjustLineIndentInner(file, offset), null);
-        }
-        catch (IncorrectOperationException e) {
-          return new Pair<Integer, IncorrectOperationException>(null, e);
-        }
-      }
-    };
-    final Pair<Integer, IncorrectOperationException> pair =
-      PostprocessReformattingAspect.getInstance(file.getProject()).disablePostprocessFormattingInside(computable);
-    if(pair.getSecond() != null) throw pair.getSecond();
-    return pair.getFirst();
-  }
-
-  public int adjustLineIndentInner(PsiFile file, int offset) throws IncorrectOperationException {
-    final PsiFile templateFile = PsiUtilBase.getTemplateLanguageFile(file);
-
-    if (templateFile != null) {
-      file = templateFile;
-    }
-
-    final PsiElement element = findElementInTreeWithFormatterEnabled(file, offset);
-    if (element == null && offset != file.getTextLength()) {
-      return offset;
-    }
-    if (element instanceof PsiComment && insideElement(element, offset) && !containsInjections(element)) {
-      return CharArrayUtil.shiftForward(file.getViewProvider().getContents(), offset, " \t");
-    }
-    final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
-    FormattingModelBuilder elementBuilder = builder;
-    if (element != null) {
-      elementBuilder = LanguageFormatting.INSTANCE.forContext(element);
-    }
-    if (builder != null && elementBuilder != null) {
-      final CodeStyleSettings settings = getSettings();
-      final CodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptions(file.getFileType());
-      final TextRange significantRange = getSignificantRange(file, offset);
-      FormattingModel model = builder.createModel(file, settings);
-
-      final Document doc = PsiDocumentManager.getInstance(myProject).getDocument(file);
-
-      if (doc != null) {
-        model = new DocumentBasedFormattingModel(model.getRootBlock(), doc, getProject(), settings, file.getFileType(), file);
+    return PostprocessReformattingAspect.getInstance(file.getProject()).disablePostprocessFormattingInside(new Computable<Integer>() {
+      public Integer compute() {
+        return doAdjustLineIndentByOffset(file, offset);
       }
-
-      return FormatterEx.getInstanceEx().adjustLineIndent(model, settings, indentOptions, offset, significantRange);
-    }
-    else {
-      return offset;
-    }
-  }
-
-  private static boolean containsInjections(PsiElement element) {
-    return element instanceof PsiLanguageInjectionHost && InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost)element);
+    });
   }
 
   @Nullable
-  public static PsiElement findElementInTreeWithFormatterEnabled(final PsiFile file, final int offset) {
+  static PsiElement findElementInTreeWithFormatterEnabled(final PsiFile file, final int offset) {
     final PsiElement bottomost = file.findElementAt(offset);
     if (bottomost != null && LanguageFormatting.INSTANCE.forContext(bottomost) != null){
       return bottomost;
@@ -297,115 +236,66 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
   public int adjustLineIndent(@NotNull final Document document, final int offset) {
     return PostprocessReformattingAspect.getInstance(getProject()).disablePostprocessFormattingInside(new Computable<Integer>() {
       public Integer compute() {
-        return adjustLineIndentInner(document, offset);
+        final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
+        documentManager.commitDocument(document);
+
+        PsiFile file = documentManager.getPsiFile(document);
+        if (file == null) return offset;
+
+        return doAdjustLineIndentByOffset(file, offset);
       }
     });
   }
 
-  public int adjustLineIndentInner(Document document, int offset) {
-    final PsiDocumentManager psiDocManager = PsiDocumentManager.getInstance(myProject);
-
-    psiDocManager.commitDocument(document);
-
-    PsiFile file = psiDocManager.getPsiFile(document);
-
-    if (file == null) return offset;
-
-    final PsiFile jspFile = PsiUtilBase.getTemplateLanguageFile(file);
-
-    if (jspFile != null) {
-      file = jspFile;
-    }
-
-    final PsiElement element = findElementInTreeWithFormatterEnabled(file, offset);
-    if (element == null && offset != file.getTextLength()) {
-      return offset;
-    }
-    if (element instanceof PsiComment && insideElement(element, offset)) {
-      return CharArrayUtil.shiftForward(file.getViewProvider().getContents(), offset, " \t");
-    }
-    final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
-    FormattingModelBuilder elementBuilder = builder;
-    if (element != null) {
-      elementBuilder = LanguageFormatting.INSTANCE.forContext(element);
-    }
-    if (builder != null && elementBuilder != null) {
-      final CodeStyleSettings settings = getSettings();
-      final CodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptions(file.getFileType());
-      final TextRange significantRange = getSignificantRange(file, offset);
-      final FormattingModel model = builder.createModel(file, settings);
-
-      final DocumentBasedFormattingModel documentBasedModel =
-        new DocumentBasedFormattingModel(model.getRootBlock(), document, getProject(), settings, file.getFileType(), file);
+  private int doAdjustLineIndentByOffset(@NotNull PsiFile file, int offset) {
+    return new CodeStyleManagerRunnable<Integer>(this) {
+      @Override
+      protected Integer doPerform(int offset, TextRange range) {
+        return FormatterEx.getInstanceEx().adjustLineIndent(myModel, mySettings, myIndentOptions, offset, mySignificantRange);
+      }
 
-      try {
-        return FormatterEx.getInstanceEx().adjustLineIndent(documentBasedModel, settings, indentOptions, offset, significantRange);
+      @Override
+      protected Integer computeValueInsidePlainComment(PsiFile file, int offset, Integer defaultValue) {
+        return CharArrayUtil.shiftForward(file.getViewProvider().getContents(), offset, " \t");
       }
-      catch (IncorrectOperationException e) {
-        LOG.error(e);
-        return offset;
+
+      @Override
+      protected Integer adjustResultForInjected(Integer result, DocumentWindow documentWindow) {
+        return documentWindow.hostToInjected(result);
       }
-    }
-    else {
-      return offset;
-    }
+    }.perform(file, offset, null, offset);
   }
 
   public void adjustLineIndent(@NotNull PsiFile file, TextRange rangeToAdjust) throws IncorrectOperationException {
-    final PsiFile templateFile = PsiUtilBase.getTemplateLanguageFile(file);
-
-    if (templateFile != null) {
-      file = templateFile;
-    }
-    final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
-    if (builder != null) {
-      final CodeStyleSettings settings = getSettings();
-      final CodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptions(file.getFileType());
-      final FormattingModel model = builder.createModel(file, settings);
-
-      final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(file);
-
-      FormatterEx.getInstanceEx().adjustLineIndentsForRange(new DocumentBasedFormattingModel(model.getRootBlock(), document, getProject(),
-                                                                                             settings, file.getFileType(), file), 
-                                                            settings,
-                                                            indentOptions,
-                                                            rangeToAdjust);
-    }
+    new CodeStyleManagerRunnable<Object>(this) {
+      @Override
+      protected Object doPerform(int offset, TextRange range) {
+        FormatterEx.getInstanceEx().adjustLineIndentsForRange(myModel, mySettings, myIndentOptions, range);
+        return null;
+      }
+    }.perform(file, -1, rangeToAdjust, null);
   }
 
   @Nullable
   public String getLineIndent(@NotNull PsiFile file, int offset) {
-    if (file instanceof PsiCompiledElement) {
-      file = (PsiFile)((PsiCompiledElement)file).getMirror();
-    }
-    final PsiElement element = findElementInTreeWithFormatterEnabled(file, offset);
-    if (element == null) {
-      return null;
-    }
-    if (element instanceof PsiComment && insideElement(element, offset)) {
-      return null;
-    }
-    final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
-    final FormattingModelBuilder elementBuilder = LanguageFormatting.INSTANCE.forContext(element);
-    if (builder != null && elementBuilder != null) {
-      final CodeStyleSettings settings = getSettings();
-      final CodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptions(file.getFileType());
-      final TextRange significantRange = getSignificantRange(file, offset);
-      final FormattingModel model = builder.createModel(file, settings);
-
-      return FormatterEx.getInstanceEx().getLineIndent(model, settings, indentOptions, offset, significantRange);
-    }
-    else {
-      return null;
-    }
+    return new CodeStyleManagerRunnable<String>(this) {
+      @Override
+      protected boolean useDocumentBaseFormattingModel() {
+        return false;
+      }
+
+      @Override
+      protected String doPerform(int offset, TextRange range) {
+        return FormatterEx.getInstanceEx().getLineIndent(myModel, mySettings, myIndentOptions, offset, mySignificantRange);
+      }
+    }.perform(file, offset, null, null);
   }
 
   @Nullable
   public String getLineIndent(@NotNull Editor editor) {
     Document doc = editor.getDocument();
     int offset = editor.getCaretModel().getOffset();
-    if( offset >= doc.getTextLength() )
-    {
+    if (offset >= doc.getTextLength()) {
       return "";
     }
 
@@ -415,27 +305,6 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
     return getLineIndent(file, offset);
   }
 
-  private static boolean insideElement(final PsiElement element, final int offset) {
-    final TextRange textRange = element.getTextRange();
-    return textRange.getStartOffset() < offset && textRange.getEndOffset() >= offset;
-  }
-
-  private static TextRange getSignificantRange(final PsiFile file, final int offset) {
-    final ASTNode elementAtOffset = SourceTreeToPsiMap.psiElementToTree(findElementInTreeWithFormatterEnabled(file, offset));
-    if (elementAtOffset == null) {
-      int significantRangeStart = CharArrayUtil.shiftBackward(file.getText(), offset - 1, "\r\t ");
-      return new TextRange(significantRangeStart, offset);
-    }
-
-    final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
-    final TextRange textRange = builder.getRangeAffectingIndent(file, offset, elementAtOffset);
-    if (textRange != null) {
-      return textRange;
-    }
-
-    return elementAtOffset.getTextRange();
-  }
-
   public boolean isLineToBeIndented(@NotNull PsiFile file, int offset) {
     if (!SourceTreeToPsiMap.hasTreeElement(file)) {
       return false;
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerRunnable.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerRunnable.java
new file mode 100644 (file)
index 0000000..57c51ab
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.impl.source.codeStyle;
+
+import com.intellij.formatting.FormattingModel;
+import com.intellij.formatting.FormattingModelBuilder;
+import com.intellij.injected.editor.DocumentWindow;
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.LanguageFormatting;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.formatter.DocumentBasedFormattingModel;
+import com.intellij.psi.impl.source.SourceTreeToPsiMap;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
+import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.util.text.CharArrayUtil;
+import org.jetbrains.annotations.Nullable;
+
+/**
+* @author nik
+*/
+abstract class CodeStyleManagerRunnable<T> {
+  protected CodeStyleSettings mySettings;
+  protected CodeStyleSettings.IndentOptions myIndentOptions;
+  protected FormattingModel myModel;
+  protected TextRange mySignificantRange;
+  private final CodeStyleManagerImpl myCodeStyleManager;
+
+  CodeStyleManagerRunnable(CodeStyleManagerImpl codeStyleManager) {
+    myCodeStyleManager = codeStyleManager;
+  }
+
+  public T perform(PsiFile file, int offset, @Nullable TextRange range, T defaultValue) {
+    if (file instanceof PsiCompiledElement) {
+      file = (PsiFile)((PsiCompiledElement)file).getMirror();
+    }
+
+    PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myCodeStyleManager.getProject());
+    Document document = documentManager.getDocument(file);
+    if (document instanceof DocumentWindow) {
+      final DocumentWindow documentWindow = (DocumentWindow)document;
+      if (range != null) {
+        range = new TextRange(documentWindow.injectedToHost(range.getStartOffset()), documentWindow.injectedToHost(range.getEndOffset()));
+      }
+      if (offset != -1) {
+        offset = documentWindow.injectedToHost(offset);
+      }
+      return adjustResultForInjected(perform(InjectedLanguageUtil.getTopLevelFile(file), offset, range, defaultValue), documentWindow);
+    }
+
+    final PsiFile templateFile = PsiUtilBase.getTemplateLanguageFile(file);
+    if (templateFile != null) {
+      file = templateFile;
+      document = documentManager.getDocument(templateFile);
+    }
+
+    PsiElement element = null;
+    if (offset != -1) {
+      element = CodeStyleManagerImpl.findElementInTreeWithFormatterEnabled(file, offset);
+      if (element == null && offset != file.getTextLength()) {
+        return defaultValue;
+      }
+      if (isInsidePlainComment(offset, element)) {
+        return computeValueInsidePlainComment(file, offset, defaultValue);
+      }
+    }
+
+    final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
+    FormattingModelBuilder elementBuilder = element != null ? LanguageFormatting.INSTANCE.forContext(element) : builder;
+    if (builder != null && elementBuilder != null) {
+      mySettings = CodeStyleSettingsManager.getSettings(myCodeStyleManager.getProject());
+      myIndentOptions = mySettings.getIndentOptions(file.getFileType());
+      mySignificantRange = offset != -1 ? getSignificantRange(file, offset) : null;
+      myModel = builder.createModel(file, mySettings);
+
+      if (document != null && useDocumentBaseFormattingModel()) {
+        myModel = new DocumentBasedFormattingModel(myModel.getRootBlock(), document, myCodeStyleManager.getProject(), mySettings, file.getFileType(), file);
+      }
+
+      final T result = doPerform(offset, range);
+      if (result != null) {
+        return result;
+      }
+    }
+    return defaultValue;
+  }
+
+  protected boolean useDocumentBaseFormattingModel() {
+    return true;
+  }
+
+  protected T adjustResultForInjected(T result, DocumentWindow documentWindow) {
+    return result;
+  }
+
+  protected T computeValueInsidePlainComment(PsiFile file, int offset, T defaultValue) {
+    return defaultValue;
+  }
+
+  @Nullable
+  protected abstract T doPerform(int offset, TextRange range);
+
+  private static boolean isInsidePlainComment(int offset, @Nullable PsiElement element) {
+    if (!(element instanceof PsiComment) || !element.getTextRange().contains(offset)) {
+      return false;
+    }
+
+    if (element instanceof PsiLanguageInjectionHost && InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost)element)) {
+      return false;
+    }
+
+    return true;
+  }
+
+  private static TextRange getSignificantRange(final PsiFile file, final int offset) {
+    final ASTNode elementAtOffset = SourceTreeToPsiMap.psiElementToTree(CodeStyleManagerImpl.findElementInTreeWithFormatterEnabled(file, offset));
+    if (elementAtOffset == null) {
+      int significantRangeStart = CharArrayUtil.shiftBackward(file.getText(), offset - 1, "\r\t ");
+      return new TextRange(significantRangeStart, offset);
+    }
+
+    final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
+    final TextRange textRange = builder.getRangeAffectingIndent(file, offset, elementAtOffset);
+    if (textRange != null) {
+      return textRange;
+    }
+
+    return elementAtOffset.getTextRange();
+  }
+}
index d06749e0b72e32808318e97b272d886a63a43db1..fcf17565f948da9e4e360e12fe0e1be107b69978 100644 (file)
@@ -40,7 +40,7 @@ public abstract class BaseRefactoringAction extends AnAction {
 
   protected abstract boolean isEnabledOnElements(PsiElement[] elements);
 
-  protected boolean isAvailableOnElementInEditor(final PsiElement element, final Editor editor) {
+  protected boolean isAvailableOnElementInEditorAndFile(final PsiElement element, final Editor editor, PsiFile file) {
     return true;
   }
 
@@ -92,7 +92,7 @@ public abstract class BaseRefactoringAction extends AnAction {
     PsiFile file = e.getData(LangDataKeys.PSI_FILE);
     if (file != null) {
       if (file instanceof PsiCompiledElement || !isAvailableForFile(file)) {
-        disableAction(e);
+        hideAction(e);
         return;
       }
     }
@@ -121,7 +121,7 @@ public abstract class BaseRefactoringAction extends AnAction {
                           !(element instanceof SyntheticElement) &&
                           isAvailableForLanguage(PsiUtilBase.getLanguageInEditor(editor, project));
       if (isVisible) {
-        boolean isEnabled = isAvailableOnElementInEditor(element, editor);
+        boolean isEnabled = isAvailableOnElementInEditorAndFile(element, editor, file);
         if (!isEnabled) {
           disableAction(e);
         }
@@ -167,9 +167,6 @@ public abstract class BaseRefactoringAction extends AnAction {
 
   private static void disableAction(final AnActionEvent e) {
     e.getPresentation().setEnabled(false);
-    if (ActionPlaces.isPopupPlace(e.getPlace()) && e.getPresentation().isVisible()) {
-      hideAction(e);
-    }
   }
 
   protected boolean isAvailableForLanguage(Language language) {
index dd167029e2c1383f422fc88b122c2313f893ee0c..aa7e78cf9ccd4b055582d1775d022daf1e6a31ad 100644 (file)
@@ -28,6 +28,7 @@ import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.extensions.Extensions;
 import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
 import com.intellij.psi.util.PsiUtilBase;
 import com.intellij.refactoring.RefactoringActionHandler;
 import com.intellij.refactoring.inline.InlineRefactoringActionHandler;
@@ -44,7 +45,7 @@ public class InlineAction extends BasePlatformRefactoringAction {
   }
 
   @Override
-  protected boolean isAvailableOnElementInEditor(PsiElement element, Editor editor) {
+  protected boolean isAvailableOnElementInEditorAndFile(PsiElement element, Editor editor, PsiFile file) {
     return hasInlineActionHandler(element, PsiUtilBase.getLanguageInEditor(editor, element.getProject()), editor);
   }
 
index 801246825261759bfc7eb3c9e87dd5ef0f963901..a78daf61ee3c0e1c6c1afdae8ed5c3f9f898724d 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.lang.Language;
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
 import com.intellij.refactoring.RefactoringActionHandler;
 import com.intellij.refactoring.safeDelete.SafeDeleteHandler;
 import com.intellij.refactoring.safeDelete.SafeDeleteProcessor;
@@ -44,7 +45,7 @@ public class SafeDeleteAction extends BaseRefactoringAction {
     return true;
   }
 
-  protected boolean isAvailableOnElementInEditor(final PsiElement element, final Editor editor) {
+  protected boolean isAvailableOnElementInEditorAndFile(final PsiElement element, final Editor editor, PsiFile file) {
     return SafeDeleteProcessor.validElement(element);
   }
 
index 0a4b82ab3e45a4b09ad0a0456d7e3eea1b8ffad0..b78ae338b4367c2865cdaeef88f6f83d75abf806 100644 (file)
@@ -24,6 +24,7 @@ import com.sun.tools.internal.xjc.util.NullStream;
 import org.junit.Test;
 
 import java.io.PrintStream;
+import java.util.List;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
@@ -39,7 +40,10 @@ public class LightPsiBuilderTest {
   private static final IElementType LEFT_BOUND = new IElementType("LEFT_BOUND", Language.ANY) {
     public boolean isLeftBound() { return true; }
   };
+  private static final IElementType COMMENT = new IElementType("COMMENT", Language.ANY);
+
   private static final TokenSet WHITESPACE_SET = TokenSet.create(WHITESPACE);
+  private static final TokenSet COMMENT_SET = TokenSet.create(COMMENT);
 
   @Test
   public void testPlain() {
@@ -279,12 +283,53 @@ public class LightPsiBuilderTest {
            "  PsiElement(LETTER)('c')\n");
   }
 
+  @Test
+  public void testCustomEdgeProcessors() throws Exception {
+    final WhitespacesAndCommentsProcessor leftEdgeProcessor = new WhitespacesAndCommentsProcessor() {
+      public int process(List<IElementType> tokens) {
+        int pos = tokens.size() - 1;
+        while (tokens.get(pos) != COMMENT && pos > 0) pos--;
+        return pos;
+      }
+    };
+    final WhitespacesAndCommentsProcessor rightEdgeProcessor = new WhitespacesAndCommentsProcessor() {
+      public int process(List<IElementType> tokens) {
+        int pos = 0;
+        while (tokens.get(pos) != COMMENT && pos < tokens.size()-1) pos++;
+        return pos + 1;
+      }
+    };
+
+    doTest("{ # i # }",
+           new Parser() {
+             public void parse(PsiBuilder builder) {
+               while (builder.getTokenType() != LETTER) builder.advanceLexer();
+               final PsiBuilder.Marker marker = builder.mark();
+               builder.advanceLexer();
+               marker.done(OTHER);
+               marker.setCustomEdgeProcessors(leftEdgeProcessor, rightEdgeProcessor);
+               while (builder.getTokenType() != null) builder.advanceLexer();
+             }
+           },
+           "Element(ROOT)\n" +
+           "  PsiElement(OTHER)('{')\n" +
+           "  PsiWhiteSpace(' ')\n" +
+           "  Element(OTHER)\n" +
+           "    PsiElement(COMMENT)('#')\n" +
+           "    PsiWhiteSpace(' ')\n" +
+           "    PsiElement(LETTER)('i')\n" +
+           "    PsiWhiteSpace(' ')\n" +
+           "    PsiElement(COMMENT)('#')\n" +
+           "  PsiWhiteSpace(' ')\n" +
+           "  PsiElement(OTHER)('}')\n");
+  }
+
   private interface Parser {
     void parse(PsiBuilder builder);
   }
 
   private static void doTest(final String text, final Parser parser, final String expected) {
-    final PsiBuilder builder = new PsiBuilderImpl(new MyTestLexer(), WHITESPACE_SET, TokenSet.EMPTY, text);
+    final PsiBuilder builder = new PsiBuilderImpl(new MyTestLexer(), WHITESPACE_SET, COMMENT_SET, text);
     final PsiBuilder.Marker rootMarker = builder.mark();
     parser.parse(builder);
     rootMarker.done(ROOT);
@@ -332,6 +377,7 @@ public class LightPsiBuilderTest {
       else if (Character.isLetter(myBuffer.charAt(myIndex))) return LETTER;
       else if (Character.isDigit(myBuffer.charAt(myIndex))) return DIGIT;
       else if (Character.isWhitespace(myBuffer.charAt(myIndex))) return WHITESPACE;
+      else if (myBuffer.charAt(myIndex) == '#') return COMMENT;
       else return OTHER;
     }
 
index a5b6e59d80105e5e99bc33a1effe6462914480a7..c5188ef5a8778127d7a0cb849ed591aac338ca3e 100644 (file)
@@ -46,7 +46,13 @@ public abstract class Language extends UserDataHolderBase {
   private final Language myBaseLanguage;
   private final String myID;
   private final String[] myMimeTypes;
-  public static final Language ANY = new Language("") { };
+  public static final Language ANY = new Language("") {
+    @Override
+    public String toString() {
+      //noinspection HardCodedStringLiteral
+      return "Language: ANY";
+    }
+  };
 
   protected Language(@NotNull @NonNls String id) {
     this(id, ArrayUtil.EMPTY_STRING_ARRAY);
@@ -145,7 +151,7 @@ public abstract class Language extends UserDataHolderBase {
   }
 
   public boolean isCaseSensitive() {
-    return myBaseLanguage != null ? myBaseLanguage.isCaseSensitive() : false;
+    return myBaseLanguage != null && myBaseLanguage.isCaseSensitive();
   }
 
   public final boolean isKindOf(Language another) {
@@ -157,8 +163,9 @@ public abstract class Language extends UserDataHolderBase {
     return false;
   }
 
-  public static @Nullable Language findLanguageByID(String id) {
-    final Collection<Language> languages = Language.getRegisteredLanguages();
+  @Nullable
+  public static Language findLanguageByID(String id) {
+    final Collection<Language> languages = getRegisteredLanguages();
     for (Language language : languages) {
       if (language.getID().equals(id)) {
         return language;
index fb56b0e559fac122f9051e1c60428e10b585b5b4..f91381b6378973a49a3582dc3213fc65d98652bc 100644 (file)
  */
 package com.intellij.openapi.editor;
 
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.editor.event.DocumentListener;
 import com.intellij.openapi.editor.markup.MarkupModel;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.util.UserDataHolder;
-import com.intellij.openapi.Disposable;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -49,6 +49,8 @@ public interface Document extends UserDataHolder {
    */
   String getText();
 
+  String getText(TextRange range);
+
   /**
    * Use this method instead of {@link #getText()} if you do not need to create a copy of the content.
    * Content represented by returned CharSequence is subject to change whenever document is modified via delete/replace/insertString method
index 8fd4b8b47bc3405fe9ee9e6eb272f531f4b74eaa..c541ab6ca086f88f1672b4d51ecdf7b0872caa00 100644 (file)
@@ -250,7 +250,7 @@ public class HighlightableComponent extends JComponent {
 
     // paint text
 
-    UIUtil.applyRenderingHints(g);
+    applyRenderingHints(g);
     FontMetrics defFontMetrics = getFontMetrics(getFont());
 
     if (myText == null) {
@@ -341,6 +341,10 @@ public class HighlightableComponent extends JComponent {
     super.paintComponent(g);
   }
 
+  protected void applyRenderingHints(Graphics g) {
+    UIUtil.applyRenderingHints(g);
+  }
+
   private int getTextOffset() {
     if (myIcon == null){
       return 2;
index 30973f38dc3ef90141e37a6610b0892cb4be644e..ebb0ad85bca38edc8f29ca53c81c40c4594dc0ea 100644 (file)
@@ -29,7 +29,9 @@ import javax.swing.table.*;
 import java.awt.*;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 public class TableView<Item> extends BaseTableView implements ItemsProvider, SelectionProvider {
@@ -115,13 +117,17 @@ public class TableView<Item> extends BaseTableView implements ItemsProvider, Sel
   }
 
   public void updateColumnSizes() {
+    final JTableHeader header = getTableHeader();
+    final TableCellRenderer defaultRenderer = header == null? null : header.getDefaultRenderer();
+
     ColumnInfo[] columns = getListTableModel().getColumnInfos();
     for (int i = 0; i < columns.length; i++) {
       final ColumnInfo columnInfo = columns[i];
       final TableColumn column = getColumnModel().getColumn(i);
-      final Component headerComponent =
-        getTableHeader().getDefaultRenderer().getTableCellRendererComponent(this, column.getHeaderValue(), false, false, 0, 0);
-      final Dimension headerSize = headerComponent.getPreferredSize();
+
+      final Component headerComponent = defaultRenderer == null? null :
+        defaultRenderer.getTableCellRendererComponent(this, column.getHeaderValue(), false, false, 0, 0);
+      final Dimension headerSize = headerComponent == null? new Dimension(0, 0) : headerComponent.getPreferredSize();
       final String maxStringValue;
       final String preferredValue;
       if (columnInfo.getWidth(this) > 0) {
index e6167ef10296d3200d0dceec22acc09b2ecbd9a2..8cfc3ccc7f78bd9c8af93f615a1a9e66b1eedcb2 100644 (file)
@@ -18,7 +18,6 @@ package com.intellij.util;
 import com.intellij.ide.FileIconPatcher;
 import com.intellij.ide.FileIconProvider;
 import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.DumbService;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.IconLoader;
@@ -26,12 +25,15 @@ import com.intellij.openapi.util.Iconable;
 import com.intellij.openapi.util.Key;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.ui.IconDeferrer;
-import com.intellij.ui.RowIcon;
 import com.intellij.ui.LayeredIcon;
+import com.intellij.ui.RowIcon;
 import com.intellij.util.ui.EmptyIcon;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
+import java.awt.*;
+import java.awt.image.BufferedImage;
 
 
 public class IconUtil {
@@ -93,7 +95,8 @@ public class IconUtil {
       if (project.isInitialized()) {
         was = Boolean.valueOf(true);
         project.putUserData(PROJECT_WAS_EVER_INTIALIZED, was);
-      } else {
+      }
+      else {
         was = Boolean.valueOf(false);
       }
     }
@@ -104,35 +107,59 @@ public class IconUtil {
   public static Icon getIcon(final VirtualFile file, final int flags, final Project project) {
     Icon lastIcon = Iconable.LastComputedIcon.get(file, flags);
 
-    return IconDeferrer.getInstance().defer(lastIcon != null ? lastIcon : file.getIcon(), new FileIconKey(file, project, flags), new Function<FileIconKey, Icon>() {
-      public Icon fun(final FileIconKey key) {
-        VirtualFile file = key.getFile();
-        int flags = key.getFlags();
-        Project project = key.getProject();
+    return IconDeferrer.getInstance()
+      .defer(lastIcon != null ? lastIcon : file.getIcon(), new FileIconKey(file, project, flags), new Function<FileIconKey, Icon>() {
+        public Icon fun(final FileIconKey key) {
+          VirtualFile file = key.getFile();
+          int flags = key.getFlags();
+          Project project = key.getProject();
 
-        if (!file.isValid() || project != null && (project.isDisposed()  || !wasEverInitialized(project))) return null;
+          if (!file.isValid() || project != null && (project.isDisposed() || !wasEverInitialized(project))) return null;
 
-        Icon providersIcon = getProvidersIcon(file, flags, project);
-        Icon icon = providersIcon == null ? file.getIcon() : providersIcon;
+          Icon providersIcon = getProvidersIcon(file, flags, project);
+          Icon icon = providersIcon == null ? file.getIcon() : providersIcon;
 
-        final boolean dumb = project != null && DumbService.getInstance(project).isDumb();
-        for (FileIconPatcher patcher : getPatchers()) {
-          if (dumb && !DumbService.isDumbAware(patcher)) {
-            continue;
+          final boolean dumb = project != null && DumbService.getInstance(project).isDumb();
+          for (FileIconPatcher patcher : getPatchers()) {
+            if (dumb && !DumbService.isDumbAware(patcher)) {
+              continue;
+            }
+
+            icon = patcher.patchIcon(icon, file, flags, project);
           }
 
-          icon = patcher.patchIcon(icon, file, flags, project);
-        }
+          if ((flags & Iconable.ICON_FLAG_READ_STATUS) != 0 && !file.isWritable()) {
+            icon = new LayeredIcon(icon, Icons.LOCKED_ICON);
+          }
 
-        if ((flags & Iconable.ICON_FLAG_READ_STATUS) != 0 && !file.isWritable()) {
-          icon = new LayeredIcon(icon, Icons.LOCKED_ICON);
+          Iconable.LastComputedIcon.put(file, icon, flags);
+
+          return icon;
         }
-        
-        Iconable.LastComputedIcon.put(file, icon, flags);
+      });
+  }
+
+  @NotNull
+  public static Icon getDisabledIcon(@NotNull final Icon icon) {
+    final BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR);
+    icon.paintIcon(new JLabel(), image.getGraphics(), 0, 0);
+    final Image disabledImage = GrayFilter.createDisabledImage(image);
+    return new Icon() {
+      @Override
+      public void paintIcon(Component c, Graphics g, int x, int y) {
+        g.drawImage(disabledImage, x, y, null);
+      }
+
+      @Override
+      public int getIconWidth() {
+        return disabledImage.getWidth(null);
+      }
 
-        return icon;
+      @Override
+      public int getIconHeight() {
+        return disabledImage.getHeight(null);
       }
-    });
+    };
   }
 
   @Nullable
index 9a93c7b85ab951fb37ab9eedd0afbec804a9db39..e0a33df3c66c100947c9b120b5720ae215029688 100644 (file)
@@ -33,7 +33,7 @@ public class ScrollTreeToCenterAction extends AnAction {
     if (component instanceof JTree) {
       JTree tree = (JTree)component;
       final int[] selection = tree.getSelectionRows();
-      if (selection.length > 0) {
+       if (selection != null && selection.length > 0) {
         TreeUtil.showRowCentered(tree, selection [0], false);
       }
     }
index 8c491af6dda856136ba3adbf70f790fed15bf3ff..f146e31ef33fc44037145de6185881b768b5d220 100644 (file)
@@ -30,6 +30,7 @@ import com.intellij.ui.IdeaBlueMetalTheme;
 import com.intellij.ui.ScreenUtil;
 import com.intellij.ui.mac.MacPopupMenuUI;
 import com.intellij.ui.plaf.beg.*;
+import com.intellij.util.IconUtil;
 import com.intellij.util.ui.UIUtil;
 import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
 import org.jdom.Element;
@@ -339,13 +340,21 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
     if (UIUtil.isUnderAquaLookAndFeel()) {
       final UIDefaults uiDefaults = UIManager.getLookAndFeelDefaults();
       uiDefaults.put("PopupMenuUI", MacPopupMenuUI.class.getCanonicalName());
-      final Icon icon = getAquaMenuInvertedIcon();
-      if (icon != null) {
-        uiDefaults.put("Menu.invertedArrowIcon", icon);
-      }
+      uiDefaults.put("Menu.invertedArrowIcon", getAquaMenuInvertedIcon());
+      uiDefaults.put("Menu.disabledArrowIcon", getAquaMenuDisabledIcon());
     }
   }
 
+  @Nullable
+  private static Icon getAquaMenuDisabledIcon() {
+    final Icon arrowIcon = (Icon)UIManager.get("Menu.arrowIcon");
+    if (arrowIcon != null) {
+      return IconUtil.getDisabledIcon(arrowIcon);
+    }
+
+    return null;
+  }
+
   @Nullable
   private static Icon getAquaMenuInvertedIcon() {
     if (!UIUtil.isUnderAquaLookAndFeel()) return null;
index 9e469401f246b29508191f5662a3679c6888fc56..85531828c0eb3bd62e2d44981828e4c84edf88c8 100644 (file)
@@ -541,6 +541,12 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
     return myText.toString();
   }
 
+  @Override
+  public String getText(TextRange range) {
+    assertReadAccessToDocumentsAllowed();
+    return myText.substring(range.getStartOffset(), range.getEndOffset()).toString();
+  }
+
   public int getTextLength() {
     assertReadAccessToDocumentsAllowed();
     return myText.length();
index 79057126e692626d71b82d9a0a1016fe8db86ef7..5dd8a221ba081e023113eb874bd7537417105e1d 100644 (file)
@@ -50,6 +50,17 @@ public class TextComponentDocument extends UserDataHolderBase implements Documen
     }
   }
 
+  @Override
+  public String getText(TextRange range) {
+    try {
+      final javax.swing.text.Document document = myTextComponent.getDocument();
+      return document.getText(range.getStartOffset(), range.getLength());
+    }
+    catch (BadLocationException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
   @NotNull
   public CharSequence getCharsSequence() {
     return getText();
index 70d3745a00b9b9156887175e479659ee9dea6b81..45a4a680d373776cd38b690705331711218d25d5 100644 (file)
@@ -39,10 +39,7 @@ import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
 import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * @author Eugene Belyaev
@@ -82,7 +79,7 @@ public class KeymapImpl implements Keymap, ExternalizableScheme {
   private KeymapImpl myParent;
   private boolean myCanModify = true;
 
-  private final Map<String, List<Shortcut>> myActionId2ListOfShortcuts = new THashMap<String, List<Shortcut>>();
+  private final Map<String, LinkedHashSet<Shortcut>> myActionId2ListOfShortcuts = new THashMap<String, LinkedHashSet<Shortcut>>();
 
   /**
    * Don't use this field directly! Use it only through <code>getKeystroke2ListOfIds</code>.
@@ -156,10 +153,10 @@ public class KeymapImpl implements Keymap, ExternalizableScheme {
     newKeymap.myKeystroke2ListOfIds = null;
     newKeymap.myMouseShortcut2ListOfIds = null;
 
-    for (Map.Entry<String, List<Shortcut>> entry : myActionId2ListOfShortcuts.entrySet()) {
-      List<Shortcut> list = entry.getValue();
+    for (Map.Entry<String, LinkedHashSet<Shortcut>> entry : myActionId2ListOfShortcuts.entrySet()) {
+      LinkedHashSet<Shortcut> list = entry.getValue();
       String key = entry.getKey();
-      newKeymap.myActionId2ListOfShortcuts.put(key, new ArrayList<Shortcut>(list));
+      newKeymap.myActionId2ListOfShortcuts.put(key, new LinkedHashSet<Shortcut>(list));
     }
 
     if (copyExternalInfo) {
@@ -209,9 +206,9 @@ public class KeymapImpl implements Keymap, ExternalizableScheme {
   }
 
   private void addShortcutSilently(String actionId, Shortcut shortcut, final boolean checkParentShortcut) {
-    List<Shortcut> list = myActionId2ListOfShortcuts.get(actionId);
+    LinkedHashSet<Shortcut> list = myActionId2ListOfShortcuts.get(actionId);
     if (list == null) {
-      list = new ArrayList<Shortcut>();
+      list = new LinkedHashSet<Shortcut>();
       myActionId2ListOfShortcuts.put(actionId, list);
       if (myParent != null) {
         // copy parent shortcuts for this actionId
@@ -235,19 +232,15 @@ public class KeymapImpl implements Keymap, ExternalizableScheme {
       removeShortcut(actionId, shortcut);
     }
   }
-  public void removeAllActionShortcuts0(String actionId) {
-    Shortcut[] allShortcuts = getShortcuts(actionId);
-    for (Shortcut shortcut : allShortcuts) {
-      removeShortcut(actionId, shortcut);
-    }
-  }
 
   public void removeShortcut(String actionId, Shortcut shortcut) {
-    List<Shortcut> list = myActionId2ListOfShortcuts.get(actionId);
+    LinkedHashSet<Shortcut> list = myActionId2ListOfShortcuts.get(actionId);
     if (list != null) {
-      for (int i = 0; i < list.size(); i++) {
-        if (shortcut.equals(list.get(i))) {
-          list.remove(i);
+      Iterator<Shortcut> it = list.iterator();
+      while (it.hasNext()) {
+        Shortcut each = it.next();
+        if (shortcut.equals(each)) {
+          it.remove();
           if (myParent != null && areShortcutsEqual(getParentShortcuts(actionId), getShortcuts(actionId))) {
             myActionId2ListOfShortcuts.remove(actionId);
           }
@@ -258,7 +251,7 @@ public class KeymapImpl implements Keymap, ExternalizableScheme {
     else if (myParent != null) {
       // put to the map the parent's bindings except for the removed binding
       Shortcut[] parentShortcuts = getParentShortcuts(actionId);
-      ArrayList<Shortcut> listOfShortcuts = new ArrayList<Shortcut>();
+      LinkedHashSet<Shortcut> listOfShortcuts = new LinkedHashSet<Shortcut>();
       for (Shortcut parentShortcut : parentShortcuts) {
         if (!shortcut.equals(parentShortcut)) {
           listOfShortcuts.add(parentShortcut);
@@ -305,7 +298,7 @@ public class KeymapImpl implements Keymap, ExternalizableScheme {
   }
 
   private <T extends Shortcut>void addAction2ShortcutsMap(final String actionId, final Map<T, List<String>> strokesMap, final Class<T> shortcutClass) {
-    List<Shortcut> listOfShortcuts = _getShortcuts(actionId);
+    LinkedHashSet<Shortcut> listOfShortcuts = _getShortcuts(actionId);
     for (Shortcut shortcut : listOfShortcuts) {
       if (!shortcutClass.isAssignableFrom(shortcut.getClass())) {
         continue;
@@ -327,7 +320,7 @@ public class KeymapImpl implements Keymap, ExternalizableScheme {
   }
 
   private void addKeystrokesMap(final String actionId, final Map<KeyStroke, List<String>> strokesMap) {
-    List<Shortcut> listOfShortcuts = _getShortcuts(actionId);
+    LinkedHashSet<Shortcut> listOfShortcuts = _getShortcuts(actionId);
     for (Shortcut shortcut : listOfShortcuts) {
       if (!(shortcut instanceof KeyboardShortcut)) {
         continue;
@@ -346,14 +339,14 @@ public class KeymapImpl implements Keymap, ExternalizableScheme {
     }
   }
 
-  private List<Shortcut> _getShortcuts(final String actionId) {
+  private LinkedHashSet<Shortcut> _getShortcuts(final String actionId) {
     KeymapManagerEx keymapManager = getKeymapManager();
-    List<Shortcut> listOfShortcuts = myActionId2ListOfShortcuts.get(actionId);
+    LinkedHashSet<Shortcut> listOfShortcuts = myActionId2ListOfShortcuts.get(actionId);
     if (listOfShortcuts != null) {
-      listOfShortcuts = new ArrayList<Shortcut>(listOfShortcuts);
+      listOfShortcuts = new LinkedHashSet<Shortcut>(listOfShortcuts);
     }
     else {
-      listOfShortcuts = new ArrayList<Shortcut>();
+      listOfShortcuts = new LinkedHashSet<Shortcut>();
     }
 
     final String actionBinding = keymapManager.getActionBinding(actionId);
@@ -506,7 +499,7 @@ public class KeymapImpl implements Keymap, ExternalizableScheme {
       return getShortcuts(keymapManager.getActionBinding(actionId));
     }
 
-    List<Shortcut> shortcuts = myActionId2ListOfShortcuts.get(actionId);
+    LinkedHashSet<Shortcut> shortcuts = myActionId2ListOfShortcuts.get(actionId);
 
     if (shortcuts == null) {
       if (myParent != null) {
@@ -647,7 +640,7 @@ public class KeymapImpl implements Keymap, ExternalizableScheme {
     }
     // Add read shortcuts
     for (String id : id2shortcuts.keySet()) {
-      myActionId2ListOfShortcuts.put(id, new ArrayList<Shortcut>(2)); // It's a trick! After that paren's shortcuts are not added to the keymap
+      myActionId2ListOfShortcuts.put(id, new LinkedHashSet<Shortcut>(2)); // It's a trick! After that parent's shortcuts are not added to the keymap
       ArrayList<Shortcut> shortcuts = id2shortcuts.get(id);
       for (Shortcut shortcut : shortcuts) {
         addShortcutSilently(id, shortcut, false);
index dd1f40bedbf1a55f09ad180dd810658bb2c298fe..ffdaeccae5d95458e061b1797a4931a2db47eb87 100644 (file)
@@ -16,6 +16,7 @@
 package com.intellij.ui.plaf.beg;
 
 import com.intellij.Patches;
+import com.intellij.openapi.util.SystemInfo;
 import com.intellij.util.ui.UIUtil;
 
 import javax.swing.*;
@@ -46,6 +47,7 @@ public class IdeaMenuUI extends BasicMenuUI{
 
   private static final Border SELECTED_BACKGROUND_PAINTER = (Border) UIManager.get("MenuItem.selectedBackgroundPainter");
   private static final Icon INVERTED_ARROW_ICON = (Icon) UIManager.get("Menu.invertedArrowIcon");
+  private static final Icon DISABLED_ARROW_ICON = (Icon) UIManager.get("Menu.disabledArrowIcon");
 
   /** invoked by reflection */
   public static ComponentUI createUI(JComponent component) {
@@ -188,8 +190,10 @@ public class IdeaMenuUI extends BasicMenuUI{
       }
       if (useCheckAndArrow()){
         try {
-          if (UIUtil.isUnderAquaLookAndFeel() && buttonmodel.isSelected() && INVERTED_ARROW_ICON != null) {
+          if (SystemInfo.isMac && INVERTED_ARROW_ICON != null && (buttonmodel.isArmed() || buttonmodel.isSelected()) && UIUtil.isUnderAquaLookAndFeel()) {
             INVERTED_ARROW_ICON.paintIcon(comp, g, ourArrowIconRect.x, ourArrowIconRect.y);
+          } else if (SystemInfo.isMac && DISABLED_ARROW_ICON != null && !buttonmodel.isEnabled() && UIUtil.isUnderAquaLookAndFeel()) {
+            DISABLED_ARROW_ICON.paintIcon(comp, g, ourArrowIconRect.x, ourArrowIconRect.y);
           } else arrowIcon.paintIcon(comp, g, ourArrowIconRect.x, ourArrowIconRect.y);
         }
         catch (NullPointerException npe) {
@@ -213,7 +217,7 @@ public class IdeaMenuUI extends BasicMenuUI{
     if (i1 == 0){
       return new MenuElement[0];
     }
-    java.awt.Container container = menuItem.getParent();
+    Container container = menuItem.getParent();
     MenuElement amenuelement1[];
     if (amenuelement[i1 - 1].getComponent() == container){
       amenuelement1 = new MenuElement[i1 + 1];
index 53f414d8734d4ebdb3c47277abe10b53702916d8..0e2ae8cecf3ee095b74a505faeeff67f33949464 100644 (file)
@@ -41,7 +41,7 @@
     <extensionPoint name="xml.implicitNamespaceDescriptorProvider"
                     interface="com.intellij.javaee.ImplicitNamespaceDescriptorProvider"/>
 
-    <extensionPoint name="xml.zenCodingGenerator" interface="com.intellij.codeInsight.template.zencoding.filters.ZenCodingGenerator"/>
+    <extensionPoint name="xml.zenCodingGenerator" interface="com.intellij.codeInsight.template.zencoding.generators.ZenCodingGenerator"/>
     <extensionPoint name="xml.zenCodingFilter" interface="com.intellij.codeInsight.template.zencoding.filters.ZenCodingFilter"/>
   </extensionPoints>
 
 
     <highlightVisitor implementation="com.intellij.codeInsight.daemon.impl.analysis.XmlHighlightVisitor"/>
 
-    <customLiveTemplate implementation="com.intellij.codeInsight.template.zencoding.XmlZenCodingTemplate"/>
+    <customLiveTemplate implementation="com.intellij.codeInsight.template.zencoding.ZenCodingTemplate"/>
 
     <externalAnnotator language="XML" implementationClass="com.intellij.lang.xml.XMLExternalAnnotator"/>
     <externalAnnotator language="HTML" implementationClass="com.intellij.lang.xml.XMLExternalAnnotator"/>
index 07ff7eb4db5074ccb2fb234a85127d2dbecb35c3..0851141fa9fac5e274c8288280f0c167990e4a6a 100644 (file)
@@ -32,9 +32,9 @@ import com.intellij.util.containers.HashMap;
 import org.jetbrains.annotations.NotNull;
 
 import java.beans.PropertyChangeListener;
-import java.util.Map;
-import java.util.List;
 import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 
 public class MockDocument implements DocumentEx {
   private final Map myUserData = new HashMap();
@@ -52,6 +52,11 @@ public class MockDocument implements DocumentEx {
     return myText.toString();
   }
 
+  @Override
+  public String getText(TextRange range) {
+    return myText.substring(range.getStartOffset(), range.getEndOffset());
+  }
+
   public void replaceText(@NotNull CharSequence chars, long newModificationStamp) {
     myText = new StringBuffer();
     myText.append(chars);
index e7df19e8c17bd2aa54decbdd4e4632b027a63e0b..8f8a06937d45d585c987111f8b1746918667e054 100644 (file)
@@ -56,7 +56,7 @@ public class ChunkExtractor {
 
   private final Lexer myLexer;
 
-  private static abstract class WeakFactory<T> {
+  private abstract static class WeakFactory<T> {
 
     private WeakReference<T> myRef;
 
@@ -246,7 +246,7 @@ public class ChunkExtractor {
   private void appendPrefix(List<TextChunk> result, int lineNumber, int columnNumber) {
     StringBuilder buffer = new StringBuilder("(");
     buffer.append(lineNumber + 1);
-    buffer.append(", ");
+    buffer.append(": ");
     buffer.append(columnNumber + 1);
     buffer.append(") ");
     TextChunk prefixChunk = new TextChunk(myColorsScheme.getAttributes(UsageTreeColors.USAGE_LOCATION), buffer.toString());
index 88db418d9d9001de1995ae1707d60a6064b613be..f182b4ab5cb9f1cae305c5170c1c67392d8ecd91 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.util.containers;
 
 import gnu.trove.THashMap;
 import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.*;
 import java.util.Stack;
@@ -56,6 +57,25 @@ public class CollectionFactory {
     return new ArrayList<T>(Arrays.asList(elements));
   }
 
+  public static <T> List<T> arrayList(@NotNull final T[] elements, final int start, final int end) {
+    if (start < 0 || start > end || end > elements.length) throw new IllegalArgumentException("start:" + start + " end:" + end + " length:" + elements.length);
+
+    return new AbstractList<T>() {
+      private final int size = end - start;
+
+      @Override
+      public T get(final int index) {
+        if (index < 0 || index >= size) throw new IndexOutOfBoundsException("index:" + index + " size:" + size);
+        return elements[start + index];
+      }
+
+      @Override
+      public int size() {
+        return size;
+      }
+    };
+  }
+
   public static <T> Stack<T> stack() {
     return new Stack<T>();
   }
index f836b3627bff399cf6f4129f0ca65d139756dfad..270bc806bdab52a6ae0e441df8f94dc73d9402ec 100644 (file)
@@ -1043,10 +1043,10 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
     }
 
     public void plus(final Pair<String, AbstractVcs> stringAbstractVcsPair) {
-      final Pair<String, AbstractVcs> correctedPair = getCorrectedPair(stringAbstractVcsPair);
-      if (correctedPair == null) return;
       myService.submit(new Runnable() {
         public void run() {
+          final Pair<String, AbstractVcs> correctedPair = getCorrectedPair(stringAbstractVcsPair);
+          if (correctedPair == null) return;
           myExecutorWrapper.submit(new Consumer<AtomicSectionsAware>() {
             public void consume(AtomicSectionsAware atomicSectionsAware) {
               myRevisionsCache.plus(correctedPair);
@@ -1057,10 +1057,10 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
     }
 
     public void minus(final Pair<String, AbstractVcs> stringAbstractVcsPair) {
-      final Pair<String, AbstractVcs> correctedPair = getCorrectedPair(stringAbstractVcsPair);
-      if (correctedPair == null) return;
       myService.submit(new Runnable() {
         public void run() {
+          final Pair<String, AbstractVcs> correctedPair = getCorrectedPair(stringAbstractVcsPair);
+          if (correctedPair == null) return;
           myExecutorWrapper.submit(new Consumer<AtomicSectionsAware>() {
             public void consume(AtomicSectionsAware atomicSectionsAware) {
               myRevisionsCache.minus(correctedPair);
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesRenameContext.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesRenameContext.java
new file mode 100644 (file)
index 0000000..b25c44a
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.vcs.changes;
+
+import java.io.File;
+import java.util.Collection;
+
+public class ChangesRenameContext {
+  private File myCurrentPath;
+
+  public ChangesRenameContext(File currentPath) {
+    myCurrentPath = currentPath;
+  }
+
+  public void checkForRename(final Collection<Change> list) {
+    for (Change change : list) {
+      if (change.getAfterRevision() != null && change.getBeforeRevision() != null) {
+        if (change.getAfterRevision().getFile().getIOFile().equals(myCurrentPath) &&
+          (! change.getBeforeRevision().getFile().getIOFile().equals(myCurrentPath))) {
+          myCurrentPath = change.getBeforeRevision().getFile().getIOFile();
+          return;
+        }
+      }
+    }
+  }
+
+  public File getCurrentPath() {
+    return myCurrentPath;
+  }
+}
index 1b5212991129ddaf3ca1515338ea3be35c14c514..509b842711418e859e28cdc30a2894128bb6ea68 100644 (file)
@@ -59,7 +59,13 @@ class ParameterClassCheckVisitor extends JavaRecursiveElementVisitor{
             return false;
         }
         final PsiMethod method = methodCallExpression.resolveMethod();
+        if (method == null) {
+            return false;
+        }
         final PsiClass aClass = method.getContainingClass();
+        if (aClass == null) {
+            return false;
+        }
         final String className = aClass.getQualifiedName();
         if (!"java.lang.Class".equals(className)) {
             return false;
@@ -89,7 +95,13 @@ class ParameterClassCheckVisitor extends JavaRecursiveElementVisitor{
             return false;
         }
         final PsiMethod method = methodCallExpression.resolveMethod();
+        if (method == null) {
+            return false;
+        }
         final PsiClass aClass = method.getContainingClass();
+        if (aClass == null) {
+            return false;
+        }
         final String className = aClass.getQualifiedName();
         if (!"java.lang.Object".equals(className)) {
             return false;
index 3faed6261dc789046a8fc0f7b377f8ab882064b1..7d2e980c6b9289152bc71230b432f658c8092518 100644 (file)
@@ -20,6 +20,8 @@ import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.*;
+import com.intellij.openapi.vcs.changes.Change;
+import com.intellij.openapi.vcs.changes.ChangesRenameContext;
 import com.intellij.openapi.vcs.changes.committed.DecoratorManager;
 import com.intellij.openapi.vcs.changes.committed.VcsCommittedListsZipper;
 import com.intellij.openapi.vcs.changes.committed.VcsCommittedViewAuxiliary;
@@ -227,7 +229,6 @@ public class GitCommittedChangeListProvider implements CommittedChangesProvider<
 
   @Override
   public Pair<CommittedChangeList, FilePath> getOneList(VirtualFile file, final VcsRevisionNumber number) throws VcsException {
-    // todo implement in proper way
     final FilePathImpl filePath = new FilePathImpl(file);
     final GitRepositoryLocation l = (GitRepositoryLocation) getLocationFor(filePath);
     VirtualFile root = LocalFileSystem.getInstance().findFileByIoFile(l.getRoot());
@@ -239,6 +240,7 @@ public class GitCommittedChangeListProvider implements CommittedChangesProvider<
     GitUtil.getLocalCommittedChanges(myProject, root, new Consumer<GitSimpleHandler>() {
       public void consume(GitSimpleHandler h) {
         h.addParameters("-n1");
+        h.addParameters("-M");
         h.addParameters(number.asString());
       }
     }, new Consumer<CommittedChangeList>() {
@@ -247,7 +249,32 @@ public class GitCommittedChangeListProvider implements CommittedChangesProvider<
         result[0] = committedChangeList;
       }
     }, false);
-    return new Pair<CommittedChangeList, FilePath>(result[0], filePath);
+    
+    final Collection<Change> changes = result[0].getChanges();
+    if (changes.size() == 1) {
+      return new Pair<CommittedChangeList, FilePath>(result[0], changes.iterator().next().getAfterRevision().getFile());
+    }
+    for (Change change : changes) {
+      if (change.getAfterRevision() != null && filePath.getIOFile().equals(change.getAfterRevision().getFile().getIOFile())) {
+        return new Pair<CommittedChangeList, FilePath>(result[0], filePath);
+      }
+    }
+    // go for history
+    final ChangesRenameContext renameContext = new ChangesRenameContext(filePath.getIOFile());
+    GitUtil.getLocalCommittedChanges(myProject, root, new Consumer<GitSimpleHandler>() {
+      public void consume(GitSimpleHandler h) {
+        h.addParameters("-M");
+        h.addParameters(number.asString() + "..");
+      }
+    }, new Consumer<CommittedChangeList>() {
+      @Override
+      public void consume(CommittedChangeList committedChangeList) {
+        final Collection<Change> list = committedChangeList.getChanges();
+        renameContext.checkForRename(list);
+      }
+    }, false);
+    renameContext.checkForRename(result[0].getChanges());
+    return new Pair<CommittedChangeList, FilePath>(result[0], new FilePathImpl(renameContext.getCurrentPath(), false));
   }
 
   public int getFormatVersion() {
index bbaeb247140cbaf85efb4d0a541e40cee9c99c2a..5d4dd5e90a007db9f5f48158876da4b3e4b4b7f8 100644 (file)
@@ -369,7 +369,9 @@ public class GitBranchConfigurations implements PersistentStateComponent<GitBran
   @Override
   public void loadState(State state) {
     synchronized (myStateLock) {
-      myConfigurations.clear();
+      if (!myConfigurations.isEmpty()) {
+        return;
+      }
       for (BranchConfiguration bc : state.CONFIGURATIONS) {
         GitBranchConfiguration n = new GitBranchConfiguration(this, bc.NAME);
         myConfigurations.put(n.getName(), n);
similarity index 97%
rename from plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/GenerateAddManagedDependencyAction.java
rename to plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/GenerateManagedDependencyAction.java
index 479896edef4d63fd17c49e06d38339db77d49bea..1ada0f64cb42544042d42b0c0143448730399b00 100644 (file)
@@ -34,8 +34,8 @@ import org.jetbrains.idea.maven.utils.MavenIcons;
 import java.util.List;
 import java.util.Set;
 
-public class GenerateAddManagedDependencyAction extends GenerateDomElementAction {
-  public GenerateAddManagedDependencyAction() {
+public class GenerateManagedDependencyAction extends GenerateDomElementAction {
+  public GenerateManagedDependencyAction() {
     super(new MavenOverridingDependencyGenerateProvider(), MavenIcons.DEPENDENCY_ICON);
   }
 
@@ -120,4 +120,4 @@ public class GenerateAddManagedDependencyAction extends GenerateDomElementAction
     }
     return false;
   }
-}
\ No newline at end of file
+}
index 237e3028541a1599f168f5bc772ae802e3417b16..3d4bb7b4aaa82bf8baccfcba8b58ac3d9d13b032 100644 (file)
@@ -18,18 +18,19 @@ package org.jetbrains.idea.maven.dom.generate;
 import com.intellij.openapi.application.Result;
 import com.intellij.openapi.command.WriteCommandAction;
 import com.intellij.openapi.editor.Editor;
-import com.intellij.util.xml.ui.actions.generate.GenerateDomElementAction;
 import com.intellij.util.xml.DomUtil;
+import com.intellij.util.xml.ui.actions.generate.GenerateDomElementAction;
+import org.jetbrains.idea.maven.dom.MavenDomBundle;
 import org.jetbrains.idea.maven.dom.MavenDomUtil;
-import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
 import org.jetbrains.idea.maven.dom.model.MavenDomParent;
+import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
 import org.jetbrains.idea.maven.navigator.SelectMavenProjectDialog;
 import org.jetbrains.idea.maven.project.MavenProject;
 import org.jetbrains.idea.maven.utils.MavenIcons;
 
 public class GenerateParentAction extends GenerateDomElementAction {
   public GenerateParentAction() {
-    super(new MavenGenerateProvider<MavenDomParent>("Generate Parent", MavenDomParent.class) {
+    super(new MavenGenerateProvider<MavenDomParent>(MavenDomBundle.message("generate.parent"), MavenDomParent.class) {
       protected MavenDomParent doGenerate(final MavenDomProjectModel mavenModel, Editor editor) {
         SelectMavenProjectDialog d = new SelectMavenProjectDialog(editor.getProject(), null);
         d.show();
index 276caebce46d16dd7bbe13b14953a644410aea02..712517dceb8ca5a9ae43b5afa9c3e1abda400ac3 100644 (file)
@@ -15,7 +15,6 @@
  */
 package org.jetbrains.idea.maven.dom.generate;
 
-import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
 import com.intellij.util.Function;
 import com.intellij.util.xml.DomElement;
@@ -28,48 +27,40 @@ import org.jetbrains.idea.maven.dom.model.MavenDomPlugin;
 import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
 import org.jetbrains.idea.maven.dom.model.MavenDomRepository;
 
-/**
- * User: Sergey.Vasiliev
- */
 public class MavenGenerateDomActionGroup extends DefaultActionGroup {
-
   public MavenGenerateDomActionGroup() {
-    // generate dependencies
-    final Function<MavenDomProjectModel, DomElement> dependenciesFunction = new Function<MavenDomProjectModel, DomElement>() {
-      public DomElement fun(MavenDomProjectModel mavenDomProjectModel) {
-        return mavenDomProjectModel.getDependencies();
-      }
-    };
-    add(createAction(MavenDomBundle.message("generate.dependency.artifact"), MavenDomDependency.class, "maven-dependency-artifact", dependenciesFunction));
-    add(createAction(MavenDomBundle.message("generate.dependency.group"), MavenDomDependency.class, "maven-dependency", dependenciesFunction));
+    add(new GenerateDependencyAction());
+    add(new GenerateManagedDependencyAction());
 
-    // generate plugins
-    Function<MavenDomProjectModel, DomElement> pluginFunction = new Function<MavenDomProjectModel, DomElement>() {
-      public DomElement fun(MavenDomProjectModel mavenDomProjectModel) {
-        return mavenDomProjectModel.getBuild().getPlugins();
-      }
-    };
-    add(createAction(MavenDomBundle.message("generate.plugin.artifact"), MavenDomPlugin.class, "maven-plugin-artifact-first", pluginFunction));
-    add(createAction(MavenDomBundle.message("generate.plugin.group"), MavenDomPlugin.class, "maven-plugin", pluginFunction));
+    addSeparator();
+    add(createAction(MavenDomBundle.message("generate.dependency.template"), MavenDomDependency.class, "maven-dependency",
+                     new Function<MavenDomProjectModel, DomElement>() {
+                       public DomElement fun(MavenDomProjectModel mavenDomProjectModel) {
+                         return mavenDomProjectModel.getDependencies();
+                       }
+                     }));
+    add(createAction(MavenDomBundle.message("generate.plugin.template"), MavenDomPlugin.class, "maven-plugin",
+                     new Function<MavenDomProjectModel, DomElement>() {
+                       public DomElement fun(MavenDomProjectModel mavenDomProjectModel) {
+                         return mavenDomProjectModel.getBuild().getPlugins();
+                       }
+                     }));
 
-    // generate repository
-    add(createAction(MavenDomRepository.class, "maven-repository", new Function<MavenDomProjectModel, DomElement>() {
-      public DomElement fun(MavenDomProjectModel mavenDomProjectModel) {
-        return mavenDomProjectModel.getRepositories();
-      }
-    }));
-  }
+    add(createAction(MavenDomBundle.message("generate.repository.template"), MavenDomRepository.class, "maven-repository",
+                     new Function<MavenDomProjectModel, DomElement>() {
+                       public DomElement fun(MavenDomProjectModel mavenDomProjectModel) {
+                         return mavenDomProjectModel.getRepositories();
+                       }
+                     }));
 
-  private static MavenCodeInsightGenerateAction createAction(String actionDescription,
-                                                      final Class<? extends DomElement> aClass,
-                                                      @NonNls @Nullable String mappingId,
-                                                      @NotNull Function<MavenDomProjectModel, DomElement> parentFunction) {
-    return new MavenCodeInsightGenerateAction(actionDescription, aClass, mappingId, parentFunction);
+    addSeparator();
+    add(new GenerateParentAction());
   }
 
-  protected static AnAction createAction(final Class<? extends DomElement> aClass,
-                                         @NonNls @Nullable String mappingId,
-                                         @NotNull Function<MavenDomProjectModel, DomElement> parentFunction) {
-    return new MavenCodeInsightGenerateAction(aClass, mappingId, parentFunction);
+  private static MavenGenerateTemplateAction createAction(String actionDescription,
+                                                             final Class<? extends DomElement> aClass,
+                                                             @NonNls @Nullable String mappingId,
+                                                             @NotNull Function<MavenDomProjectModel, DomElement> parentFunction) {
+    return new MavenGenerateTemplateAction(actionDescription, aClass, mappingId, parentFunction);
   }
 }
\ No newline at end of file
similarity index 62%
rename from plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/MavenCodeInsightGenerateAction.java
rename to plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/MavenGenerateTemplateAction.java
index 731d62707038778924ee8dd1c8f4e82843e99200..d52a9b930c3d50010ae50c42dcdbff37b2013a14 100644 (file)
@@ -7,9 +7,7 @@ import com.intellij.psi.xml.XmlFile;
 import com.intellij.util.Function;
 import com.intellij.util.xml.DomElement;
 import com.intellij.util.xml.ElementPresentationManager;
-import com.intellij.util.xml.TypeNameManager;
 import com.intellij.util.xml.ui.actions.generate.GenerateDomElementAction;
-import com.intellij.util.xml.ui.actions.generate.GenerateDomElementProvider;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.maven.dom.MavenDomUtil;
@@ -18,29 +16,17 @@ import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
 /**
  * User: Sergey.Vasiliev
  */
-public class MavenCodeInsightGenerateAction extends GenerateDomElementAction {
-
-  public MavenCodeInsightGenerateAction(@NotNull Class<? extends DomElement> childElementClass,
-                                        @Nullable final String mappingId,
-                                        @NotNull Function<MavenDomProjectModel, DomElement> parentFunction) {
-    this(TypeNameManager.getTypeName(childElementClass), childElementClass, mappingId, parentFunction);
-  }
-
-  public MavenCodeInsightGenerateAction(@NotNull final String description,
+public class MavenGenerateTemplateAction extends GenerateDomElementAction {
+  public MavenGenerateTemplateAction(@NotNull final String description,
                                         @NotNull final Class<? extends DomElement> childElementClass,
                                         @Nullable final String mappingId,
                                         @NotNull Function<MavenDomProjectModel, DomElement> parentFunction) {
     super(new MavenGenerateDomElementProvider(description, childElementClass, mappingId, parentFunction));
 
     getTemplatePresentation().setIcon(ElementPresentationManager.getIconForClass(childElementClass));
-  }                       
-
-  public MavenCodeInsightGenerateAction(final GenerateDomElementProvider generateProvider) {
-    super(generateProvider);
   }
 
   protected boolean isValidForFile(Project project, Editor editor, PsiFile file) {
     return file instanceof XmlFile && MavenDomUtil.getMavenDomModel(file, MavenDomProjectModel.class) != null;
   }
-
 }
\ No newline at end of file
similarity index 51%
rename from plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/extract/ExtractDependenciesAction.java
rename to plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/extract/ExtractManagedDependenciesAction.java
index a328710c864915cb7fc182b7e12af5951648c046..809d10c157a44e3627c09ae842ebe1b4a6edb549 100644 (file)
@@ -22,6 +22,7 @@ import com.intellij.openapi.command.WriteCommandAction;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.Pair;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.xml.XmlElement;
@@ -42,9 +43,9 @@ import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
 import java.util.Collections;
 import java.util.Set;
 
-public class ExtractDependenciesAction extends BaseRefactoringAction {
+public class ExtractManagedDependenciesAction extends BaseRefactoringAction {
 
-  public ExtractDependenciesAction() {
+  public ExtractManagedDependenciesAction() {
     setInjectedContext(true);
   }
 
@@ -63,7 +64,6 @@ public class ExtractDependenciesAction extends BaseRefactoringAction {
 
   protected RefactoringActionHandler getHandler(DataContext dataContext) {
     return new MyRefactoringActionHandler();
-
   }
 
   @Override
@@ -71,75 +71,101 @@ public class ExtractDependenciesAction extends BaseRefactoringAction {
     return MavenDomUtil.isMavenFile(file);
   }
 
-  private static class MyRefactoringActionHandler implements RefactoringActionHandler {
-    public void invoke(@NotNull final Project project, final Editor editor, PsiFile file, DataContext dataContext) {
-      final MavenDomDependency dependency =
-        DomUtil.findDomElement(file.findElementAt(editor.getCaretModel().getOffset()), MavenDomDependency.class);
+  @Override
+  protected boolean isAvailableOnElementInEditorAndFile(PsiElement element, Editor editor, PsiFile file) {
+    if (!super.isAvailableOnElementInEditorAndFile(element, editor, file)) return false;
+    return findDependencyAndParent(file, editor) != null;
+  }
+
+  private static Pair<MavenDomDependency, Set<MavenDomProjectModel>> findDependencyAndParent(PsiFile file, Editor editor) {
+    final MavenDomDependency dependency = DomUtil.findDomElement(file.findElementAt(editor.getCaretModel().getOffset()),
+                                                                 MavenDomDependency.class);
+    if (dependency == null || isManagedDependency(dependency)) return null;
 
-      if (dependency != null && !isManagedDependency(dependency)) {
-        Function<MavenDomProjectModel, Set<MavenDomDependency>> funOccurrences = getOccurencesFunction(dependency);
+    Set<MavenDomProjectModel> parents = getParentProjects(file.getProject(), file);
+    if (parents.isEmpty()) return null;
+
+    return Pair.create(dependency, parents);
+  }
+
+  @NotNull
+  private static Set<MavenDomProjectModel> getParentProjects(@NotNull Project project, @NotNull PsiFile file) {
+    final MavenDomProjectModel model = MavenDomUtil.getMavenDomModel(file, MavenDomProjectModel.class);
+
+    if (model == null) return Collections.emptySet();
+    return MavenDomProjectProcessorUtils.collectParentProjects(model);
+  }
 
-        final ProcessData processData =
-          getProcessData(project, getParentProjects(project, file), funOccurrences, dependency.getExclusions().getXmlElement() != null);
+  private static boolean isManagedDependency(@NotNull MavenDomDependency dependency) {
+    return MavenDomProjectProcessorUtils.searchManagingDependency(dependency) != null;
+  }
 
-        if (processData != null) {
+  private static class MyRefactoringActionHandler implements RefactoringActionHandler {
+    public void invoke(@NotNull final Project project, final Editor editor, PsiFile file, DataContext dataContext) {
+      Pair<MavenDomDependency, Set<MavenDomProjectModel>> depAndParents = findDependencyAndParent(file, editor);
+      if (depAndParents == null) return;
 
-          final MavenDomProjectModel model = processData.getModel();
-          final Set<MavenDomDependency> usages = processData.getUsages();
-          final boolean extractExclusions = processData.isExtractExclusions();
+      final MavenDomDependency dependency = depAndParents.first;
+      Set<MavenDomProjectModel> parent = depAndParents.second;
 
+      Function<MavenDomProjectModel, Set<MavenDomDependency>> funOccurrences = getOccurencesFunction(dependency);
+      final ProcessData processData = getProcessData(project, parent, funOccurrences, dependency.getExclusions().getXmlElement() != null);
+      if (processData == null) return;
 
-          assert model != null;
-          assert usages != null;
+      final MavenDomProjectModel model = processData.getModel();
+      final Set<MavenDomDependency> usages = processData.getUsages();
+      final boolean extractExclusions = processData.isExtractExclusions();
 
-          new WriteCommandAction(project, getFiles(file, model, usages)) {
-            @Override
-            protected void run(Result result) throws Throwable {
-              MavenDomDependency addedDependency = model.getDependencyManagement().getDependencies().addDependency();
-              addedDependency.getGroupId().setStringValue(dependency.getGroupId().getStringValue());
-              addedDependency.getArtifactId().setStringValue(dependency.getArtifactId().getStringValue());
-              addedDependency.getVersion().setStringValue(dependency.getVersion().getStringValue());
-              String typeValue = dependency.getType().getStringValue();
 
-              dependency.getVersion().undefine();
+      assert model != null;
+      assert usages != null;
 
-              if (typeValue != null) {
-                addedDependency.getType().setStringValue(typeValue);
-                dependency.getType().undefine();
-              }
+      new WriteCommandAction(project, getFiles(file, model, usages)) {
+        @Override
+        protected void run(Result result) throws Throwable {
+          MavenDomDependency addedDependency = model.getDependencyManagement().getDependencies().addDependency();
+          addedDependency.getGroupId().setStringValue(dependency.getGroupId().getStringValue());
+          addedDependency.getArtifactId().setStringValue(dependency.getArtifactId().getStringValue());
+          addedDependency.getVersion().setStringValue(dependency.getVersion().getStringValue());
+          String typeValue = dependency.getType().getStringValue();
 
-              String classifier = dependency.getClassifier().getStringValue();
-              if (classifier != null) {
-                addedDependency.getClassifier().setStringValue(classifier);
-                dependency.getClassifier().undefine();
-              }
+          dependency.getVersion().undefine();
 
-              String systemPath = dependency.getSystemPath().getStringValue();
-              if (systemPath != null) {
-                addedDependency.getSystemPath().setStringValue(systemPath);
-                dependency.getSystemPath().undefine();
-              }
+          if (typeValue != null) {
+            addedDependency.getType().setStringValue(typeValue);
+            dependency.getType().undefine();
+          }
 
+          String classifier = dependency.getClassifier().getStringValue();
+          if (classifier != null) {
+            addedDependency.getClassifier().setStringValue(classifier);
+            dependency.getClassifier().undefine();
+          }
 
-              if (extractExclusions) {
-                MavenDomExclusions addedExclusions = addedDependency.getExclusions();
-                for (MavenDomExclusion exclusion : dependency.getExclusions().getExclusions()) {
-                  MavenDomExclusion domExclusion = addedExclusions.addExclusion();
+          String systemPath = dependency.getSystemPath().getStringValue();
+          if (systemPath != null) {
+            addedDependency.getSystemPath().setStringValue(systemPath);
+            dependency.getSystemPath().undefine();
+          }
 
-                  domExclusion.getGroupId().setStringValue(exclusion.getGroupId().getStringValue());
-                  domExclusion.getArtifactId().setStringValue(exclusion.getArtifactId().getStringValue());
-                }
 
-                dependency.getExclusions().undefine();
-              }
+          if (extractExclusions) {
+            MavenDomExclusions addedExclusions = addedDependency.getExclusions();
+            for (MavenDomExclusion exclusion : dependency.getExclusions().getExclusions()) {
+              MavenDomExclusion domExclusion = addedExclusions.addExclusion();
 
-              for (MavenDomDependency usage : usages) {
-                usage.getVersion().undefine();
-              }
+              domExclusion.getGroupId().setStringValue(exclusion.getGroupId().getStringValue());
+              domExclusion.getArtifactId().setStringValue(exclusion.getArtifactId().getStringValue());
             }
-          }.execute();
+
+            dependency.getExclusions().undefine();
+          }
+
+          for (MavenDomDependency usage : usages) {
+            usage.getVersion().undefine();
+          }
         }
-      }
+      }.execute();
     }
 
     private static PsiFile[] getFiles(@NotNull PsiFile file, @NotNull MavenDomProjectModel model, @NotNull Set<MavenDomDependency> usages) {
@@ -162,9 +188,9 @@ public class ExtractDependenciesAction extends BaseRefactoringAction {
     @Nullable
     private static ProcessData getProcessData(@NotNull Project project,
 
-                                                                                      @NotNull Set<MavenDomProjectModel> models,
-                                                                                      @NotNull Function<MavenDomProjectModel, Set<MavenDomDependency>> funOccurrences,
-                                                                                      boolean hasExclusions) {
+                                              @NotNull Set<MavenDomProjectModel> models,
+                                              @NotNull Function<MavenDomProjectModel, Set<MavenDomDependency>> funOccurrences,
+                                              boolean hasExclusions) {
       if (models.size() == 0) return null;
 
       if (models.size() == 1 && !hasExclusions) {
@@ -174,13 +200,15 @@ public class ExtractDependenciesAction extends BaseRefactoringAction {
         }
       }
 
-      SelectMavenProjectDialog dialog = new SelectMavenProjectDialog(project, models, funOccurrences,hasExclusions);
+      SelectMavenProjectDialog dialog = new SelectMavenProjectDialog(project, models, funOccurrences, hasExclusions);
       dialog.show();
 
       if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
         MavenDomProjectModel model = dialog.getSelectedProject();
 
-        return new ProcessData(model, dialog.isReplaceAllOccurrences() ? funOccurrences.fun(model) : Collections.<MavenDomDependency>emptySet(), dialog.isExtractExclusions());
+        return new ProcessData(model,
+                               dialog.isReplaceAllOccurrences() ? funOccurrences.fun(model) : Collections.<MavenDomDependency>emptySet(),
+                               dialog.isExtractExclusions());
       }
 
       return null;
@@ -198,18 +226,6 @@ public class ExtractDependenciesAction extends BaseRefactoringAction {
       };
     }
 
-    @NotNull
-    private Set<MavenDomProjectModel> getParentProjects(@NotNull Project project, @NotNull PsiFile file) {
-      final MavenDomProjectModel model = MavenDomUtil.getMavenDomModel(file, MavenDomProjectModel.class);
-
-      if (model == null) return Collections.emptySet();
-      return MavenDomProjectProcessorUtils.collectParentProjects(model);
-    }
-
-    private static boolean isManagedDependency(@NotNull MavenDomDependency dependency) {
-      return MavenDomProjectProcessorUtils.searchManagingDependency(dependency) != null;
-    }
-
     public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
     }
 
index 07a7444ec72891a91be939c0f78d6e13bb2e0cfa..7697257d2dd7d6b845cff58e85a51a8617dd6152 100644 (file)
@@ -13,6 +13,7 @@ import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.util.Factory;
+import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.JarFileSystem;
@@ -26,9 +27,8 @@ import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.xml.*;
 import com.intellij.refactoring.RefactoringActionHandler;
 import com.intellij.refactoring.actions.BaseRefactoringAction;
-import com.intellij.usageView.*;
+import com.intellij.usageView.UsageInfo;
 import com.intellij.usages.*;
-import com.intellij.usages.UsageViewManager;
 import com.intellij.util.Processor;
 import com.intellij.util.containers.hash.HashSet;
 import org.jetbrains.annotations.NotNull;
@@ -74,60 +74,93 @@ public class IntroducePropertyAction extends BaseRefactoringAction {
            && virtualFile.getFileSystem() != JarFileSystem.getInstance();
   }
 
+  @Override
+  protected boolean isAvailableOnElementInEditorAndFile(PsiElement element, Editor editor, PsiFile file) {
+    if (!super.isAvailableOnElementInEditorAndFile(element, editor, file)) return false;
+    return getSelectedElementAndTextRange(editor, file) != null;
+  }
+
+  @Nullable
+  public static Pair<XmlElement, TextRange> getSelectedElementAndTextRange(Editor editor, final PsiFile file) {
+    final int startOffset = editor.getSelectionModel().getSelectionStart();
+    final int endOffset = editor.getSelectionModel().getSelectionEnd();
+
+    final PsiElement elementAtStart = file.findElementAt(startOffset);
+    if (elementAtStart == null) return null;
+    final PsiElement elementAtEnd = file.findElementAt(endOffset - 1);
+    if (elementAtEnd == null) return null;
+
+    PsiElement elementAt = PsiTreeUtil.findCommonParent(elementAtStart, elementAtEnd);
+    if (elementAt instanceof XmlToken) elementAt = elementAt.getParent();
+
+    if (elementAt instanceof XmlText || elementAt instanceof XmlAttributeValue) {
+      TextRange range;
+
+      if (editor.getSelectionModel().hasSelection()) {
+        range = new TextRange(startOffset, endOffset);
+      }
+      else {
+        range = elementAt.getTextRange(); 
+      }
+
+      return Pair.create((XmlElement)elementAt, range);
+    }
+
+    return null;
+  }
+
   private static class MyRefactoringActionHandler implements RefactoringActionHandler {
     public void invoke(@NotNull final Project project, final Editor editor, PsiFile file, DataContext dataContext) {
-      if (!editor.getSelectionModel().hasSelection()) return;
       PsiDocumentManager.getInstance(project).commitAllDocuments();
 
-      final int startOffset = editor.getSelectionModel().getSelectionStart();
-      final int endOffset = editor.getSelectionModel().getSelectionEnd();
+      Pair<XmlElement, TextRange> elementAndRange = getSelectedElementAndTextRange(editor, file);
+      if (elementAndRange == null) return;
 
-      XmlElement selectedElement = getSelectedElement(file, startOffset, endOffset);
+      XmlElement selectedElement = elementAndRange.first;
+      final TextRange range = elementAndRange.second;
 
-      if (selectedElement != null) {
-        String stringValue = selectedElement.getText();
-        if (stringValue != null) {
+      String stringValue = selectedElement.getText();
+      if (stringValue == null) return;
 
-          final MavenDomProjectModel model = MavenDomUtil.getMavenDomModel(file, MavenDomProjectModel.class);
-          final String selectedString = editor.getSelectionModel().getSelectedText();
+      final MavenDomProjectModel model = MavenDomUtil.getMavenDomModel(file, MavenDomProjectModel.class);
+      final String selectedString = editor.getDocument().getText(range);
 
-          Set<TextRange> ranges = getPropertiesTextRanges(stringValue);
-          int offsetInElement = startOffset - selectedElement.getTextOffset();
+      Set<TextRange> ranges = getPropertiesTextRanges(stringValue);
+      int offsetInElement = range.getStartOffset() - selectedElement.getTextOffset();
 
-          if (model == null ||
-              StringUtil.isEmptyOrSpaces(selectedString) ||
-              isInsideTextRanges(ranges, offsetInElement, offsetInElement + selectedString.length())) {
-            return;
-          }
+      if (model == null ||
+          StringUtil.isEmptyOrSpaces(selectedString) ||
+          isInsideTextRanges(ranges, offsetInElement, offsetInElement + selectedString.length())) {
+        return;
+      }
 
-          IntroducePropertyDialog dialog = new IntroducePropertyDialog(project, selectedElement, model, null, selectedString);
-          dialog.show();
+      editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset());
 
-          if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
-            final String propertyName = dialog.getEnteredName();
-            final String replaceWith = PREFIX + propertyName + SUFFIX;
-            final MavenDomProjectModel selectedProject = dialog.getSelectedProject();
+      IntroducePropertyDialog dialog = new IntroducePropertyDialog(project, selectedElement, model, null, selectedString);
+      dialog.show();
+      if (dialog.getExitCode() != DialogWrapper.OK_EXIT_CODE) return;
 
-            if (ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(getFiles(file, selectedProject)).hasReadonlyFiles()) {
-              return;
-            }
+      final String propertyName = dialog.getEnteredName();
+      final String replaceWith = PREFIX + propertyName + SUFFIX;
+      final MavenDomProjectModel selectedProject = dialog.getSelectedProject();
 
-            new WriteCommandAction(project) {
-              @Override
-              protected void run(Result result) throws Throwable {
-                editor.getDocument().replaceString(startOffset, endOffset, replaceWith);
-                PsiDocumentManager.getInstance(project).commitAllDocuments();
+      if (ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(getFiles(file, selectedProject)).hasReadonlyFiles()) {
+        return;
+      }
 
-                createMavenProperty(selectedProject, propertyName, selectedString);
+      new WriteCommandAction(project) {
+        @Override
+        protected void run(Result result) throws Throwable {
+          editor.getDocument().replaceString(range.getStartOffset(), range.getEndOffset(), replaceWith);
+          PsiDocumentManager.getInstance(project).commitAllDocuments();
 
-                PsiDocumentManager.getInstance(project).commitAllDocuments();
-              }
-            }.execute();
+          createMavenProperty(selectedProject, propertyName, selectedString);
 
-            showFindUsages(project, propertyName, selectedString, replaceWith, selectedProject);
-          }
+          PsiDocumentManager.getInstance(project).commitAllDocuments();
         }
-      }
+      }.execute();
+
+      showFindUsages(project, propertyName, selectedString, replaceWith, selectedProject);
     }
 
     private static VirtualFile[] getFiles(PsiFile file, MavenDomProjectModel model) {
@@ -200,23 +233,6 @@ public class IntroducePropertyAction extends BaseRefactoringAction {
       return findModel;
     }
 
-    @Nullable
-    public static XmlElement getSelectedElement(final PsiFile file, final int startOffset, final int endOffset) {
-      final PsiElement elementAtStart = file.findElementAt(startOffset);
-      if (elementAtStart == null) return null;
-      final PsiElement elementAtEnd = file.findElementAt(endOffset - 1);
-      if (elementAtEnd == null) return null;
-
-      PsiElement elementAt = PsiTreeUtil.findCommonParent(elementAtStart, elementAtEnd);
-      if (elementAt instanceof XmlToken) elementAt = elementAt.getParent();
-
-      if (elementAt instanceof XmlText || elementAt instanceof XmlAttributeValue) {
-        return (XmlElement)elementAt;
-      }
-
-      return null;
-    }
-
     public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
     }
 
index 1b4e3e54ed60381b0e5832c792f37b9105cecaf2..b4e59d8fdf74f62797d5b89f560e596e0bb9a711 100644 (file)
@@ -108,12 +108,15 @@ public class MavenModuleImporter {
 
   private void configDependencies() {
     for (MavenArtifact artifact : myMavenProject.getDependencies()) {
+      if (!myMavenProject.isSupportedDependency(artifact)) continue;
+
       DependencyScope scope = selectScope(artifact.getScope(