diff --git a/platform/lang-api/src/com/intellij/patterns/VirtualFilePattern.java b/platform/lang-api/src/com/intellij/patterns/VirtualFilePattern.java index 3b26feb8e9c1..4515c6eb4a7f 100644 --- a/platform/lang-api/src/com/intellij/patterns/VirtualFilePattern.java +++ b/platform/lang-api/src/com/intellij/patterns/VirtualFilePattern.java @@ -74,6 +74,14 @@ public class VirtualFilePattern extends TreeElementPattern pathPattern) { + return with(new PatternCondition("withName") { + public boolean accepts(@NotNull final VirtualFile virtualFile, final ProcessingContext context) { + return pathPattern.accepts(virtualFile.getPath(), context); + } + }); + } + public VirtualFilePattern xmlWithRootTag(final ElementPattern tagNamePattern) { return with(new PatternCondition("xmlWithRootTag") { public boolean accepts(@NotNull final VirtualFile virtualFile, final ProcessingContext context) { diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.form b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.form index 803ac485f05e..57585a586b2e 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.form +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.form @@ -76,19 +76,11 @@ - - - - - - - - - + diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java index 7e2d139a31e9..09d095f8b5cd 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/EditLibraryDialog.java @@ -51,7 +51,6 @@ public class EditLibraryDialog extends DialogWrapper { private JButton myAddFileButton; private JButton myRemoveFileButton; private JBTable myFileTable; - private JButton myAttachFromButton; private Project myProject; private FileTableModel myFileTableModel; private VirtualFile mySelectedFile; @@ -70,13 +69,6 @@ public class EditLibraryDialog extends DialogWrapper { } }); - myAttachFromButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - attachFromDirectory(); - } - }); - myFileTableModel = new FileTableModel(); myFileTable.setModel(myFileTableModel); @@ -147,19 +139,15 @@ public class EditLibraryDialog extends DialogWrapper { FileChooserDescriptor chooserDescriptor = new LibFileChooserDescriptor(); VirtualFile[] files = FileChooser.chooseFiles(myProject, chooserDescriptor); if (files.length == 1 && files[0] != null) { - myFileTableModel.addFile(files[0]); - } - } - - private void attachFromDirectory() { - FileChooserDescriptor chooserDescriptor = new FileChooserDescriptor(false, true, false, false, false, false); - chooserDescriptor.setTitle("Select a directory to attach files from"); //TODO Move to resources - VirtualFile[] files = FileChooser.chooseFiles(myProject, chooserDescriptor); - if (files.length == 1 && files[0] != null) { - VirtualFile chosenDir = files[0]; - if (chosenDir.isDirectory() && chosenDir.isValid()) { - if (myLibName.getText().isEmpty()) myLibName.setText(chosenDir.getName()); - addRecursively(chosenDir); + VirtualFile selectedFile = files[0]; + if (selectedFile.isValid()) { + if (selectedFile.isDirectory()) { + if (myLibName.getText().isEmpty()) myLibName.setText(selectedFile.getName()); + addRecursively(selectedFile); + } + else { + myFileTableModel.addFile(selectedFile); + } } } } @@ -181,13 +169,13 @@ public class EditLibraryDialog extends DialogWrapper { private class LibFileChooserDescriptor extends FileChooserDescriptor { public LibFileChooserDescriptor() { - super (true, false, false, true, false, false); - setTitle("Select library file"); //TODO Move to resources + super (true, true, false, true, false, false); + setTitle("Select library file or directory"); //TODO Move to resources } @Override public boolean isFileSelectable(VirtualFile file) { - if (!myProvider.acceptsExtension(file.getExtension())) return false; + if (!file.isDirectory() && !myProvider.acceptsExtension(file.getExtension())) return false; return super.isFileSelectable(file); } diff --git a/platform/lang-impl/src/com/intellij/refactoring/actions/BasePlatformRefactoringAction.java b/platform/lang-impl/src/com/intellij/refactoring/actions/BasePlatformRefactoringAction.java index beb4c62c1e73..a74ccd064db5 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/actions/BasePlatformRefactoringAction.java +++ b/platform/lang-impl/src/com/intellij/refactoring/actions/BasePlatformRefactoringAction.java @@ -61,8 +61,8 @@ public abstract class BasePlatformRefactoringAction extends BaseRefactoringActio @Override protected final RefactoringActionHandler getHandler(DataContext dataContext) { - PsiElement element; + PsiElement element = null; Editor editor = LangDataKeys.EDITOR.getData(dataContext); PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext); if (editor != null && file != null) { @@ -75,14 +75,18 @@ public abstract class BasePlatformRefactoringAction extends BaseRefactoringActio } } - element = LangDataKeys.PSI_ELEMENT.getData(dataContext); - if (element != null) { - RefactoringActionHandler handler = getHandler(element.getLanguage(), element); + PsiElement referenced = LangDataKeys.PSI_ELEMENT.getData(dataContext); + if (referenced != null) { + RefactoringActionHandler handler = getHandler(referenced.getLanguage(), referenced); if (handler != null) { return handler; } } + if (element == null) { + element = referenced; + } + final Language[] languages = LangDataKeys.CONTEXT_LANGUAGES.getData(dataContext); if (languages != null) { for (Language language : languages) { diff --git a/platform/platform-api/src/com/intellij/patterns/StringPattern.java b/platform/platform-api/src/com/intellij/patterns/StringPattern.java index 43459f96a7f6..aded18ec8c40 100644 --- a/platform/platform-api/src/com/intellij/patterns/StringPattern.java +++ b/platform/platform-api/src/com/intellij/patterns/StringPattern.java @@ -15,6 +15,7 @@ */ package com.intellij.patterns; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ProcessingContext; import dk.brics.automaton.Automaton; @@ -28,11 +29,13 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Collections; import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; /** * @author peter */ public class StringPattern extends ObjectPattern { + private static final Logger LOG = Logger.getInstance("#com.intellij.patterns.StringPattern"); private static final InitialPatternCondition CONDITION = new InitialPatternCondition(String.class) { public boolean accepts(@Nullable final Object o, final ProcessingContext context) { return o instanceof String; @@ -94,7 +97,19 @@ public class StringPattern extends ObjectPattern { if (escaped.equals(s)) { return equalTo(s); } - final Pattern pattern = Pattern.compile(s); + final Pattern pattern; + try { + pattern = Pattern.compile(s); + } + catch (PatternSyntaxException e) { + LOG.error(e); + return with(new PatternCondition("neverMatches") { + @Override + public boolean accepts(@NotNull String s, ProcessingContext context) { + return false; + } + }); + } return with(new ValuePatternCondition("matches") { public boolean accepts(@NotNull final String str, final ProcessingContext context) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 372874e7967f..67d4cd713ea5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -1043,7 +1043,24 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi // optimization: do not do column calculations here since we are interested in line number only public int offsetToVisualLine(int offset) { int line = calcLogicalLineNumber(offset); - return logicalToVisualLine(line); + int lineStartOffset = myDocument.getLineStartOffset(line); + int result = logicalToVisualLine(line); + + // There is a possible case that logical line that contains target offset is soft-wrapped (represented in more than one visual + // line). Hence, we need to perform necessary adjustments to the visual line that is used to show logical line start if necessary. + int i = getSoftWrapModel().getSoftWrapIndex(lineStartOffset); + if (i < 0) { + i = -i - 1; + } + List softWraps = getSoftWrapModel().getRegisteredSoftWraps(); + for (; i < softWraps.size(); i++) { + SoftWrap softWrap = softWraps.get(i); + if (softWrap.getStart() > offset) { + break; + } + result++; // Assuming that every soft wrap contains only one virtual line feed symbol + } + return result; } private int logicalToVisualLine(int line) { assertReadAccess(); diff --git a/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java b/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java index 2faaaac0478d..7cfb26b7259a 100644 --- a/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java +++ b/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java @@ -204,16 +204,22 @@ public abstract class ResourceManager { } @Nullable - public String getFileResourceType(@NotNull PsiFile file) { - PsiDirectory dir = file.getContainingDirectory(); - if (dir == null) return null; - PsiDirectory possibleResDir = dir.getParentDirectory(); - if (possibleResDir == null || !isResourceDir(possibleResDir.getVirtualFile())) { - return null; - } - String type = getResourceTypeByDirName(dir.getName()); - if (type == null) return null; - return isCorrectFileName(type, file.getName()) ? type : null; + public String getFileResourceType(@NotNull final PsiFile file) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Nullable + @Override + public String compute() { + PsiDirectory dir = file.getContainingDirectory(); + if (dir == null) return null; + PsiDirectory possibleResDir = dir.getParentDirectory(); + if (possibleResDir == null || !isResourceDir(possibleResDir.getVirtualFile())) { + return null; + } + String type = getResourceTypeByDirName(dir.getName()); + if (type == null) return null; + return isCorrectFileName(type, file.getName()) ? type : null; + } + }); } @NotNull diff --git a/plugins/groovy/resources/standardDsls/gantScript.gdsl b/plugins/groovy/resources/standardDsls/gantScript.gdsl index 35648d9e665b..98760c63c949 100644 --- a/plugins/groovy/resources/standardDsls/gantScript.gdsl +++ b/plugins/groovy/resources/standardDsls/gantScript.gdsl @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -def ctx = context(scope: scriptScope(), scripttype : ["gant"]) +def ctx = context(scope: scriptScope(), scriptType : "gant") contributor ([ctx], { property name:"ant", type:"org.codehaus.gant.GantBuilder" diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/Context.groovy b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/Context.groovy index 3a4ba24cc0dd..bdfce4c779b4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/Context.groovy +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/Context.groovy @@ -2,15 +2,12 @@ package org.jetbrains.plugins.groovy.dsl.toplevel import com.intellij.openapi.util.text.StringUtil import com.intellij.patterns.ElementPattern +import com.intellij.patterns.StandardPatterns import org.jetbrains.plugins.groovy.dsl.toplevel.scopes.Scope import static com.intellij.patterns.PlatformPatterns.psiFile import static com.intellij.patterns.PlatformPatterns.virtualFile -import org.jetbrains.plugins.groovy.dsl.GroovyClassDescriptor -import com.intellij.util.ProcessingContext -import org.jetbrains.plugins.groovy.lang.psi.GroovyFile -import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector -/** + /** * @author ilyas */ class Context { @@ -28,19 +25,14 @@ class Context { addFilter new FileContextFilter(psiFile().withVirtualFile(vfilePattern)) } - List scripttype = args.scripttype - if (scripttype) { - addFilter(new ContextFilter() { - @Override - boolean isApplicable(GroovyClassDescriptor descriptor, ProcessingContext ctx) { - def file = descriptor.placeFile - if (file instanceof GroovyFile && ((GroovyFile)file).isScript()) { - def scripTypeId = GroovyScriptTypeDetector.getScriptType((GroovyFile)file).getId() - return scripttype.contains(scripTypeId) - } - return false - } - }) + String scriptType = args.scriptType + if (scriptType) { + addFilter(new ScriptTypeFilter(scriptType)) + } + + String pathRegexp = args.pathRegexp + if (pathRegexp) { + addFilter new FileContextFilter(psiFile().withVirtualFile(virtualFile().withPath(StandardPatterns.string().matches(pathRegexp)))) } // filter by scope first, then by ctype diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/ScriptTypeFilter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/ScriptTypeFilter.java new file mode 100644 index 000000000000..ff6923bd2398 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/ScriptTypeFilter.java @@ -0,0 +1,42 @@ +/* + * 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 org.jetbrains.plugins.groovy.dsl.toplevel; + +import com.intellij.psi.PsiFile; +import com.intellij.util.ProcessingContext; +import org.jetbrains.plugins.groovy.dsl.GroovyClassDescriptor; +import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; + +/** + * @author peter + */ +public class ScriptTypeFilter implements ContextFilter { + private final String myScriptType; + + public ScriptTypeFilter(String scriptType) { + myScriptType = scriptType; + } + + public boolean isApplicable(GroovyClassDescriptor descriptor, ProcessingContext ctx) { + PsiFile file = descriptor.getPlaceFile(); + if (file instanceof GroovyFile && ((GroovyFile)file).isScript()) { + return myScriptType.contains(GroovyScriptTypeDetector.getScriptType((GroovyFile)file).getId()); + } + return false; + } + +} \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyDslTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyDslTest.groovy index d8bd3e6b71b6..54fab61016b2 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyDslTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyDslTest.groovy @@ -137,4 +137,17 @@ contributor([:]){category 'MyCategory'}"""); myFixture.testCompletion(getTestName(false) + ".groovy", getTestName(false) + "_after.groovy") } + + public void testPathRegexp() { + final PsiFile file = myFixture.addFileToProject("a.gdsl", "contributor(pathRegexp: '.*aaa.*') { property name:'fffooo', type:'int' }"); + GroovyDslFileIndex.activateUntilModification(file.virtualFile) + + myFixture.configureFromExistingVirtualFile myFixture.addFileToProject("aaa/foo.groovy", "fffx").virtualFile + myFixture.completeBasic() + assertOrderedEquals myFixture.lookupElementStrings, 'fffooo' + + myFixture.configureFromExistingVirtualFile myFixture.addFileToProject("bbb/foo.groovy", "fffx").virtualFile + myFixture.completeBasic() + assertEmpty myFixture.lookupElementStrings + } } diff --git a/xml/impl/src/com/intellij/codeInsight/completion/ExtendedTagInsertHandler.java b/xml/impl/src/com/intellij/codeInsight/completion/ExtendedTagInsertHandler.java index 5be551653479..dc6dafe87453 100644 --- a/xml/impl/src/com/intellij/codeInsight/completion/ExtendedTagInsertHandler.java +++ b/xml/impl/src/com/intellij/codeInsight/completion/ExtendedTagInsertHandler.java @@ -115,9 +115,12 @@ public class ExtendedTagInsertHandler extends XmlTagInsertHandler { } protected boolean isNamespaceBound(PsiElement psiElement) { - final XmlTag tag = (XmlTag)psiElement.getParent(); + PsiElement parent = psiElement.getParent(); + if (!(parent instanceof XmlTag)) return false; + final XmlTag tag = (XmlTag)parent; final XmlElementDescriptor tagDescriptor = tag.getDescriptor(); final String tagNamespace = tag.getNamespace(); + assert myNamespace != null; return tagDescriptor != null && !(tagDescriptor instanceof AnyXmlElementDescriptor) && myNamespace.equals(tagNamespace); } diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java index b2f7936299eb..6781c1c22dd1 100644 --- a/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java +++ b/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java @@ -43,6 +43,7 @@ public class XmlSmartCompletionProvider { final XmlTag tag = (XmlTag)element.getParent(); final XmlTag parentTag = tag.getParentTag(); + if (parentTag == null) return; final XmlContentDFA dfa = XmlContentDFA.getContentDFA(parentTag); if (dfa == null) return; ApplicationManager.getApplication().runReadAction(new Runnable() { diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFA.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFA.java index 448ce5214f3c..cf49e5ae339c 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFA.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlContentDFA.java @@ -32,7 +32,7 @@ public abstract class XmlContentDFA { public abstract void transition(XmlTag xmlTag); @Nullable - public static XmlContentDFA getContentDFA(XmlTag parentTag) { + public static XmlContentDFA getContentDFA(@NotNull XmlTag parentTag) { XmlContentDFA contentDFA = XsContentDFA.createContentDFA(parentTag); if (contentDFA != null) return contentDFA; return XmlContentDFAImpl.createContentDFA(parentTag); diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XsContentDFA.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XsContentDFA.java index 8fc66ab1361d..11fefd140226 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XsContentDFA.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XsContentDFA.java @@ -63,7 +63,7 @@ class XsContentDFA extends XmlContentDFA { private final XmlElementDescriptor[] myElementDescriptors; @Nullable - public static XmlContentDFA createContentDFA(XmlTag parentTag) { + public static XmlContentDFA createContentDFA(@NotNull XmlTag parentTag) { final PsiFile file = parentTag.getContainingFile().getOriginalFile(); if (!(file instanceof XmlFile)) return null; XSModel xsModel = ApplicationManager.getApplication().runReadAction(new NullableComputable() { diff --git a/xml/impl/src/com/intellij/xml/actions/GenerateXmlTagAction.java b/xml/impl/src/com/intellij/xml/actions/GenerateXmlTagAction.java index 303015b731ed..6bfddfd9f708 100644 --- a/xml/impl/src/com/intellij/xml/actions/GenerateXmlTagAction.java +++ b/xml/impl/src/com/intellij/xml/actions/GenerateXmlTagAction.java @@ -141,7 +141,7 @@ public class GenerateXmlTagAction extends SimpleCodeInsightAction { } @Nullable - private static XmlTag getAnchor(XmlTag contextTag, Editor editor, XmlElementDescriptor selected) { + private static XmlTag getAnchor(@NotNull XmlTag contextTag, Editor editor, XmlElementDescriptor selected) { XmlContentDFA contentDFA = XmlContentDFA.getContentDFA(contextTag); int offset = editor.getCaretModel().getOffset(); if (contentDFA == null) { diff --git a/xml/impl/src/com/intellij/xml/index/XmlIndex.java b/xml/impl/src/com/intellij/xml/index/XmlIndex.java index 6482bdd920fa..d466188c5ca0 100644 --- a/xml/impl/src/com/intellij/xml/index/XmlIndex.java +++ b/xml/impl/src/com/intellij/xml/index/XmlIndex.java @@ -60,8 +60,7 @@ public abstract class XmlIndex extends FileBasedIndexExtension { @Override public boolean contains(VirtualFile file) { final VirtualFile parent = file.getParent(); - assert parent != null; - return parent.getName().equals("standardSchemas") || projectScope.contains(file); + return parent != null && (parent.getName().equals("standardSchemas") || projectScope.contains(file)); } @Override diff --git a/xml/impl/src/com/intellij/xml/util/XmlUtil.java b/xml/impl/src/com/intellij/xml/util/XmlUtil.java index dd87449badc8..54c573491f95 100644 --- a/xml/impl/src/com/intellij/xml/util/XmlUtil.java +++ b/xml/impl/src/com/intellij/xml/util/XmlUtil.java @@ -1282,7 +1282,7 @@ public class XmlUtil { final char ch = unquotedValue.charAt(i); if (!Character.isJavaIdentifierPart(ch) && ch != ':' && ch != '-') { final XmlFile file = PsiTreeUtil.getParentOfType(context, XmlFile.class); - if (file != null) return !tagFromTemplateFramework(file.getDocument().getRootTag()); + if (file != null) return !tagFromTemplateFramework(file.getRootTag()); return false; } } diff --git a/xml/openapi/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java b/xml/openapi/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java index 298b8dd3fb61..f1ce3969dfc2 100644 --- a/xml/openapi/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java +++ b/xml/openapi/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java @@ -43,7 +43,7 @@ public class DefaultXmlSuppressionProvider extends XmlSuppressionProvider { } public boolean isSuppressedFor(PsiElement element, String inspectionId) { - final XmlTag tag = PsiTreeUtil.getContextOfType(element, XmlTag.class, false); + final XmlTag tag = element instanceof XmlFile ? ((XmlFile)element).getRootTag() : PsiTreeUtil.getContextOfType(element, XmlTag.class, false); return tag != null && findSuppression(tag, inspectionId, element) != null; }