Merge remote branch 'origin/master'

This commit is contained in:
irengrig
2012-07-03 19:38:29 +04:00
139 changed files with 2641 additions and 952 deletions
@@ -31,7 +31,6 @@ import com.intellij.psi.filters.ClassFilter;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.filters.TrueFilter;
import com.intellij.psi.filters.element.ExcludeDeclaredFilter;
import com.intellij.psi.filters.types.AssignableFromFilter;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Consumer;
@@ -74,6 +73,9 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
if (SkipAutopopupInStrings.isInStringLiteral(position)) {
return true;
}
if (PsiTreeUtil.getParentOfType(position, PsiComment.class, false) != null) {
return true;
}
return false;
}
@@ -83,22 +85,8 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
@NotNull final Consumer<LookupElement> consumer) {
final PsiElement insertedElement = parameters.getPosition();
final ElementFilter filter;
if (JavaSmartCompletionContributor.AFTER_THROW_NEW.accepts(insertedElement) ||
JavaCompletionContributor.INSIDE_METHOD_THROWS_CLAUSE.accepts(insertedElement) ||
JavaCompletionContributor.IN_CATCH_TYPE.accepts(insertedElement) ||
JavaCompletionContributor.IN_MULTI_CATCH_TYPE.accepts(insertedElement)) {
filter = new AssignableFromFilter(CommonClassNames.JAVA_LANG_THROWABLE);
}
else if (JavaCompletionContributor.IN_RESOURCE_TYPE.accepts(insertedElement)) {
filter = new AssignableFromFilter(CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE);
}
else if (IN_TYPE_PARAMETER.accepts(insertedElement)) {
filter = new ExcludeDeclaredFilter(new ClassFilter(PsiTypeParameter.class));
}
else {
filter = TrueFilter.INSTANCE;
}
final ElementFilter filter =
IN_TYPE_PARAMETER.accepts(insertedElement) ? new ExcludeDeclaredFilter(new ClassFilter(PsiTypeParameter.class)) : TrueFilter.INSTANCE;
final boolean inJavaContext = parameters.getPosition() instanceof PsiIdentifier;
final boolean afterNew = AFTER_NEW.accepts(insertedElement);
@@ -120,13 +108,10 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
}
}
final boolean lookingForAnnotations = psiElement().afterLeaf("@").accepts(insertedElement);
final boolean pkgContext = JavaCompletionUtil.inSomePackage(insertedElement);
AllClassesGetter.processJavaClasses(parameters, matcher, filterByScope, new Consumer<PsiClass>() {
@Override
public void consume(PsiClass psiClass) {
if (lookingForAnnotations && !psiClass.isAnnotationType()) return;
if (filter.isAcceptable(psiClass, insertedElement)) {
if (!inJavaContext) {
consumer.consume(AllClassesGetter.createLookupItem(psiClass, AllClassesGetter.TRY_SHORTENING));
@@ -628,7 +628,7 @@ public class JavaCompletionData extends JavaAwareCompletionData {
return false;
}
if (psiElement().withSuperParent(2, PsiConditionalExpression.class).accepts(position)) {
if (psiElement().withSuperParent(2, PsiConditionalExpression.class).andNot(psiElement().insideStarting(psiElement(PsiConditionalExpression.class))).accepts(position)) {
return false;
}
@@ -49,11 +49,11 @@ import java.util.regex.Pattern;
public class FileHeaderChecker {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.defaultFileTemplateUsage.FileHeaderChecker");
static ProblemDescriptor checkFileHeader(final PsiFile file, final InspectionManager manager, boolean onTheFly) {
static ProblemDescriptor checkFileHeader(@NotNull final PsiFile file, final InspectionManager manager, boolean onTheFly) {
FileTemplate template = FileTemplateManager.getInstance().getDefaultTemplate(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME);
TIntObjectHashMap<String> offsetToProperty = new TIntObjectHashMap<String>();
String templateText = template.getText().trim();
String regex = templateToRegex(templateText, offsetToProperty);
String regex = templateToRegex(templateText, offsetToProperty, file.getProject());
regex = StringUtil.replace(regex, "with", "(?:with|by)");
regex = ".*("+regex+").*";
String fileText = file.getText();
@@ -144,9 +144,9 @@ public class FileHeaderChecker {
return new LocalQuickFix[]{replaceTemplateFix,editFileTemplateFix};
}
private static String templateToRegex(final String text, TIntObjectHashMap<String> offsetToProperty) {
private static String templateToRegex(final String text, TIntObjectHashMap<String> offsetToProperty, Project project) {
String regex = text;
@NonNls Collection<String> properties = new ArrayList<String>((Collection)FileTemplateManager.getInstance().getDefaultProperties().keySet());
@NonNls Collection<String> properties = new ArrayList<String>((Collection)FileTemplateManager.getInstance().getDefaultProperties(project).keySet());
properties.add("PACKAGE_NAME");
regex = escapeRegexChars(regex);
@@ -120,7 +120,7 @@ public class JavaDirectoryServiceImpl extends CoreJavaDirectoryService {
FileTemplate template = FileTemplateManager.getInstance().getInternalTemplate(templateName);
Properties defaultProperties = FileTemplateManager.getInstance().getDefaultProperties();
Properties defaultProperties = FileTemplateManager.getInstance().getDefaultProperties(dir.getProject());
Properties properties = new Properties(defaultProperties);
properties.setProperty(FileTemplate.ATTRIBUTE_NAME, name);
@@ -187,14 +187,14 @@ public class CreateClassUtil {
}
@Nullable
public static PsiClass createClassNamed(String newClassName, String templateName, PsiDirectory directory) throws IncorrectOperationException {
return createClassNamed(newClassName, new Properties(FileTemplateManager.getInstance().getDefaultProperties()), templateName, directory);
public static PsiClass createClassNamed(String newClassName, String templateName, @NotNull PsiDirectory directory) throws IncorrectOperationException {
return createClassNamed(newClassName, FileTemplateManager.getInstance().getDefaultProperties(directory.getProject()), templateName, directory);
}
@Nullable
public static PsiClass createClassNamed(String newClassName, Map classProperties, String templateName, PsiDirectory directory)
public static PsiClass createClassNamed(String newClassName, Map classProperties, String templateName, @NotNull PsiDirectory directory)
throws IncorrectOperationException {
Properties defaultProperties = FileTemplateManager.getInstance().getDefaultProperties();
Properties defaultProperties = FileTemplateManager.getInstance().getDefaultProperties(directory.getProject());
Properties properties = new Properties(defaultProperties);
properties.putAll(classProperties);
@@ -235,7 +235,7 @@ public class CreateClassUtil {
try {
final Properties properties = ApplicationManager.getApplication().isUnitTestMode() ?
new Properties() :
FileTemplateManager.getInstance().getDefaultProperties();
FileTemplateManager.getInstance().getDefaultProperties(classDirectory.getProject());
return createClassNamed(className, new Properties(properties), templateName, classDirectory);
}
catch (IncorrectOperationException e) {
@@ -63,7 +63,7 @@ public class RenameJavaMethodProcessor extends RenameJavaMemberProcessor {
PsiMethod method = (PsiMethod) psiElement;
Set<PsiMethod> methodAndOverriders = new HashSet<PsiMethod>();
Set<PsiClass> containingClasses = new HashSet<PsiClass>();
List<PsiElement> renamedReferences = new ArrayList<PsiElement>();
LinkedHashSet<PsiElement> renamedReferences = new LinkedHashSet<PsiElement>();
List<MemberHidesOuterMemberUsageInfo> outerHides = new ArrayList<MemberHidesOuterMemberUsageInfo>();
List<MemberHidesStaticImportUsageInfo> staticImportHides = new ArrayList<MemberHidesStaticImportUsageInfo>();
@@ -53,7 +53,7 @@ public class InheritanceUtil {
return isInheritorOrSelf(aClass, baseClass, checkDeep);
}
public static boolean processSupers(@Nullable PsiClass aClass, boolean includeSelf, Processor<PsiClass> superProcessor) {
public static boolean processSupers(@Nullable PsiClass aClass, boolean includeSelf, @NotNull Processor<PsiClass> superProcessor) {
if (aClass == null) return true;
if (includeSelf && !superProcessor.process(aClass)) return false;
@@ -61,7 +61,7 @@ public class InheritanceUtil {
return processSupers(aClass, superProcessor, new THashSet<PsiClass>());
}
private static boolean processSupers(@NotNull PsiClass aClass, Processor<PsiClass> superProcessor, Set<PsiClass> visited) {
private static boolean processSupers(@NotNull PsiClass aClass, @NotNull Processor<PsiClass> superProcessor, @NotNull Set<PsiClass> visited) {
if (!visited.add(aClass)) return true;
for (final PsiClass intf : aClass.getInterfaces()) {
@@ -82,11 +82,11 @@ public class InheritanceUtil {
return false;
}
public static boolean isInheritor(@Nullable PsiClass psiClass, final String baseClassName) {
public static boolean isInheritor(@Nullable PsiClass psiClass, @NotNull final String baseClassName) {
return isInheritor(psiClass, false, baseClassName);
}
public static boolean isInheritor(@Nullable PsiClass psiClass, final boolean strict, final String baseClassName) {
public static boolean isInheritor(@Nullable PsiClass psiClass, final boolean strict, @NotNull final String baseClassName) {
if (psiClass == null) {
return false;
}
@@ -105,21 +105,22 @@ public class InheritanceUtil {
* @param results
* @param includeNonProject
*/
public static void getSuperClasses(PsiClass aClass, Set<PsiClass> results, boolean includeNonProject) {
getSuperClassesOfList(aClass.getSuperTypes(), results, includeNonProject);
public static void getSuperClasses(@NotNull PsiClass aClass, @NotNull Set<PsiClass> results, boolean includeNonProject) {
getSuperClassesOfList(aClass.getSuperTypes(), results, includeNonProject, new THashSet<PsiClass>(), aClass.getManager());
}
public static void getSuperClassesOfList(PsiClassType[] types, Set<PsiClass> results,
boolean includeNonProject) {
private static void getSuperClassesOfList(@NotNull PsiClassType[] types,
@NotNull Set<PsiClass> results,
boolean includeNonProject,
@NotNull Set<PsiClass> visited,
@NotNull PsiManager manager) {
for (PsiClassType type : types) {
PsiClass resolved = type.resolve();
if (resolved != null) {
if (!results.contains(resolved)) {
if (includeNonProject || resolved.getManager().isInProject(resolved)) {
results.add(resolved);
}
getSuperClasses(resolved, results, includeNonProject);
if (resolved != null && visited.add(resolved)) {
if (includeNonProject || manager.isInProject(resolved)) {
results.add(resolved);
}
getSuperClassesOfList(resolved.getSuperTypes(), results, includeNonProject, visited, manager);
}
}
}
@@ -50,7 +50,7 @@ public class PsiLiteralExpressionImpl
@Override
public PsiType getType() {
final IElementType type = getFirstChildNode().getElementType();
final IElementType type = getLiteralElementType();
if (type == JavaTokenType.INTEGER_LITERAL) {
return PsiType.INT;
}
@@ -80,6 +80,10 @@ public class PsiLiteralExpressionImpl
return null;
}
public IElementType getLiteralElementType() {
return getFirstChildNode().getElementType();
}
public String getCanonicalText() {
final TreeElement literal = getFirstChildNode();
final IElementType type = literal.getElementType();
@@ -88,8 +92,7 @@ public class PsiLiteralExpressionImpl
@Override
public Object getValue() {
final TreeElement literal = getFirstChildNode();
final IElementType type = literal.getElementType();
final IElementType type = getLiteralElementType();
String text = NUMERIC_LITERALS.contains(type) ? getCanonicalText().toLowerCase() : getCanonicalText();
final int textLength = text.length();
@@ -172,19 +175,8 @@ public class PsiLiteralExpressionImpl
return Character.valueOf(chars.charAt(0));
}
if (type == JavaTokenType.STRING_LITERAL) {
if (StringUtil.endsWithChar(text, '\"')) {
if (textLength == 1) return null;
text = text.substring(1, textLength - 1);
}
else {
if (text.startsWith(QUOT) && text.endsWith(QUOT) && textLength > QUOT.length()) {
text = text.substring(QUOT.length(), textLength - QUOT.length());
}
else {
return null;
}
}
return internedParseStringCharacters(text);
String innerText = getInnerText();
return innerText == null ? null : internedParseStringCharacters(innerText);
}
if (type == JavaTokenType.TRUE_KEYWORD) {
return Boolean.TRUE;
@@ -196,6 +188,25 @@ public class PsiLiteralExpressionImpl
return null;
}
@Nullable
public String getInnerText() {
String text = getCanonicalText();
int textLength = text.length();
if (StringUtil.endsWithChar(text, '\"')) {
if (textLength == 1) return null;
text = text.substring(1, textLength - 1);
}
else {
if (text.startsWith(QUOT) && text.endsWith(QUOT) && textLength > QUOT.length()) {
text = text.substring(QUOT.length(), textLength - QUOT.length());
}
else {
return null;
}
}
return text;
}
// convert text to number according to radix specified
// if number is more than maxBits bits long, throws NumberFormatException
private static long parseDigits(final String text, final int bitsInRadix, final int maxBits) throws NumberFormatException {
@@ -0,0 +1,5 @@
public class Util {
int goo() {
ret<caret>cond ? 1: 0;
}
}
@@ -65,6 +65,7 @@ public class ClassNameCompletionTest extends LightFixtureCompletionTestCase {
String path = "/afterNewThrowable";
configureByFile(path + "/before1.java");
myFixture.type('\n');
checkResultByFile(path + "/after1.java");
}
@@ -81,6 +82,7 @@ public class ClassNameCompletionTest extends LightFixtureCompletionTestCase {
String path = "/afterNewThrowable";
configureByFile(path + "/before2.java");
myFixture.type('\n');
checkResultByFile(path + "/after2.java");
}
@@ -92,6 +92,7 @@ public class KeywordCompletionTest extends LightCompletionTestCase {
public void testNewInMethodRefs() throws Exception { doTest(false); }
public void testAbstractInInterface() throws Exception { doTest(1, "abstract"); }
public void testCharInAnnotatedParameter() throws Exception { doTest(1, "char"); }
public void testReturnInTernary() throws Exception { doTest(1, "return"); }
public void testTryInExpression() throws Exception {
configureByFile(BASE_PATH + "/" + getTestName(true) + ".java");
@@ -20,6 +20,7 @@
<orderEntry type="library" name="Groovy" level="project" />
<orderEntry type="module" module-name="testFramework" exported="" />
<orderEntry type="module" module-name="relaxng" exported="" scope="TEST" />
<orderEntry type="module" module-name="idea-ui" exported="" scope="TEST" />
</component>
<component name="copyright">
<Base>
@@ -17,7 +17,7 @@ import java.util.Set;
* @author Eugene Zhuravlev
* Date: 9/24/11
*/
class JavacFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
class JavacFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> implements StandardJavaFileManager{
private final Context myContext;
private Map<File, Set<File>> myOutputsMap = Collections.emptyMap();
@@ -37,26 +37,36 @@ class JavacFileManager extends ForwardingJavaFileManager<StandardJavaFileManager
myContext = context;
}
public boolean setOutputDirectories(final Map<File, Set<File>> outputDirToSrcRoots) {
public void setOutputDirectories(final Map<File, Set<File>> outputDirToSrcRoots) throws IOException{
for (File outputDir : outputDirToSrcRoots.keySet()) {
// this will validate output dirs
if (!setLocation(StandardLocation.CLASS_OUTPUT, Collections.singleton(outputDir))) {
return false;
}
setLocation(StandardLocation.CLASS_OUTPUT, Collections.singleton(outputDir));
}
myOutputsMap = outputDirToSrcRoots;
return true;
}
public boolean setLocation(Location location, Iterable<? extends File> path) {
try {
getStdManager().setLocation(location, path);
}
catch (IOException e) {
myContext.reportMessage(Diagnostic.Kind.ERROR, e.getMessage());
return false;
}
return true;
public void setLocation(Location location, Iterable<? extends File> path) throws IOException{
getStdManager().setLocation(location, path);
}
public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files) {
return getStdManager().getJavaFileObjectsFromFiles(files);
}
public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
return getStdManager().getJavaFileObjects(files);
}
public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
return getStdManager().getJavaFileObjectsFromStrings(names);
}
public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
return getStdManager().getJavaFileObjects(names);
}
public Iterable<? extends File> getLocation(Location location) {
return getStdManager().getLocation(location);
}
public boolean isSameFile(FileObject a, FileObject b) {
@@ -213,4 +223,8 @@ class JavacFileManager extends ForwardingJavaFileManager<StandardJavaFileManager
throw new CompilationCanceledException();
}
}
public Context getContext() {
return myContext;
}
}
@@ -7,6 +7,7 @@ import org.jetbrains.jps.server.ClasspathBootstrap;
import javax.tools.*;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
@@ -41,19 +42,38 @@ public class JavacMain {
fileManager.handleOption("-bootclasspath", Collections.singleton("").iterator()); // this will clear cached stuff
fileManager.handleOption("-extdirs", Collections.singleton("").iterator()); // this will clear cached stuff
fileManager.setOutputDirectories(outputDirToRoots);
try {
fileManager.setOutputDirectories(outputDirToRoots);
}
catch (IOException e) {
fileManager.getContext().reportMessage(Diagnostic.Kind.ERROR, e.getMessage());
return false;
}
if (!classpath.isEmpty()) {
if (!fileManager.setLocation(StandardLocation.CLASS_PATH, classpath)) {
try {
fileManager.setLocation(StandardLocation.CLASS_PATH, classpath);
}
catch (IOException e) {
fileManager.getContext().reportMessage(Diagnostic.Kind.ERROR, e.getMessage());
return false;
}
}
if (!platformClasspath.isEmpty()) {
if (!fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, platformClasspath)) {
try {
fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, platformClasspath);
}
catch (IOException e) {
fileManager.getContext().reportMessage(Diagnostic.Kind.ERROR, e.getMessage());
return false;
}
}
if (!sourcePath.isEmpty()) {
if (!fileManager.setLocation(StandardLocation.SOURCE_PATH, sourcePath)) {
try {
fileManager.setLocation(StandardLocation.SOURCE_PATH, sourcePath);
}
catch (IOException e) {
fileManager.getContext().reportMessage(Diagnostic.Kind.ERROR, e.getMessage());
return false;
}
}
@@ -17,7 +17,6 @@ import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* WARNING: Loaded via reflection, do not delete
@@ -28,7 +27,7 @@ import java.util.concurrent.ConcurrentHashMap;
class OptimizedFileManager extends DefaultFileManager {
private boolean myUseZipFileIndex;
private final Map<File, Archive> myArchives;
private final Map<File, Boolean> myIsFile = new ConcurrentHashMap<File, Boolean>();
private final Map<File, Boolean> myIsFile = new HashMap<File, Boolean>();
private final Map<InputFileObject, SoftReference<CharBuffer>> myContentCache = new HashMap<InputFileObject, SoftReference<CharBuffer>>();
private final Map<File, SoftReference<File[]>> myDirectoryCache = new HashMap<File, SoftReference<File[]>>();
public static final File[] NULL_FILE_ARRAY = new File[0];
@@ -271,20 +270,12 @@ class OptimizedFileManager extends DefaultFileManager {
}
private class InputFileObject extends BaseFileObject {
/** The file's name.
*/
private String name;
/** The underlying file.
*/
final File f;
public InputFileObject(File f) {
this(f.getName(), f);
}
public InputFileObject(String name, File f) {
this.name = name;
this.f = f;
}
@@ -306,15 +297,16 @@ class OptimizedFileManager extends DefaultFileManager {
@Deprecated
public String getName() {
return name;
return f.getPath();
}
public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) {
String n = cn + kind.extension;
if (name.equals(n)) {
public boolean isNameCompatible(String simpleName, JavaFileObject.Kind kind) {
final String n = simpleName + kind.extension;
final String fileName = f.getName();
if (fileName.equals(n)) {
return true;
}
if (name.equalsIgnoreCase(n)) {
if (fileName.equalsIgnoreCase(n)) {
try {
// allow for Windows
return (f.getCanonicalFile().getName().equals(n));
@@ -4,7 +4,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.incremental.Utils;
import javax.tools.*;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import java.io.*;
import java.net.URI;
import java.util.Arrays;
@@ -39,7 +40,7 @@ public final class OutputFileObject extends SimpleJavaFileObject {
myOutputRoot = outputRoot;
myRelativePath = relativePath;
myFile = file;
myClassName = className;
myClassName = className != null? className.replace('/', '.') : null;
mySourceFile = srcUri != null? Utils.convertToFile(srcUri) : null;
}
Binary file not shown.
@@ -276,7 +276,7 @@ public class CompositeElement extends TreeElement {
final int len = getTextLength();
if (startStamp != myModificationsCount) {
throw new AssertionError("Tree changed while calculating text");
throw new AssertionError("Tree changed while calculating text. startStamp:"+startStamp+"; current:"+myModificationsCount+"; myHC:"+myHC+"; assertThreading:"+ASSERT_THREADING+"; Thread.holdsLock(START_OFFSET_LOCK):"+Thread.holdsLock(START_OFFSET_LOCK)+"; Thread.holdsLock(PSI_LOCK):"+Thread.holdsLock(PsiLock.LOCK));
}
char[] buffer = new char[len];
@@ -181,7 +181,8 @@ public class LowLevelSearchUtil {
}
public static int searchWord(@NotNull CharSequence text,
char[] textArray, int startOffset,
char[] textArray,
int startOffset,
int endOffset,
@NotNull StringSearcher searcher,
@Nullable ProgressIndicator progress) {
@@ -303,7 +303,7 @@ public abstract class PsiElementPattern<T extends PsiElement,Self extends PsiEle
});
}
public Self insideStarting(final ElementPattern<PsiElement> ancestor) {
public Self insideStarting(final ElementPattern<? extends PsiElement> ancestor) {
return with(new PatternCondition<PsiElement>("insideStarting") {
@Override
public boolean accepts(@NotNull PsiElement start, ProcessingContext context) {
@@ -304,7 +304,7 @@
</component>
</children>
</grid>
<grid id="7f3f5" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="7f3f5" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -339,9 +339,27 @@
</component>
<vspacer id="82d85">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="9558b" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="2006d" class="javax.swing.JCheckBox" binding="myCbShowQuickDocOnCheckBox" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="checkbox.show.quick.doc.on.mouse.over"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
<grid id="5df80" binding="myHighlightSettingsPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,8 +21,10 @@ import com.intellij.application.options.OptionsApplicabilityFilter;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInsight.daemon.impl.IdentifierHighlighterPass;
import com.intellij.codeInsight.documentation.QuickDocOnMouseOverManager;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
@@ -83,6 +85,7 @@ public class EditorOptionsPanel {
private JTextField myCustomSoftWrapIndent;
private JCheckBox myCbShowAllSoftWraps;
private JCheckBox myPreselectCheckBox;
private JCheckBox myCbShowQuickDocOnCheckBox;
private final ErrorHighlightingPanel myErrorHighlightingPanel = new ErrorHighlightingPanel();
private final MyConfigurable myConfigurable;
@@ -156,6 +159,7 @@ public class EditorOptionsPanel {
}
myCbEnsureBlankLineBeforeCheckBox.setSelected(editorSettings.isEnsureNewLineAtEOF());
myCbShowQuickDocOnCheckBox.setSelected(editorSettings.isShowQuickDocOnMouseOverElement());
// Advanced mouse
myCbEnableDnD.setSelected(editorSettings.isDndEnabled());
@@ -235,6 +239,12 @@ public class EditorOptionsPanel {
editorSettings.setEnsureNewLineAtEOF(myCbEnsureBlankLineBeforeCheckBox.isSelected());
if (myCbShowQuickDocOnCheckBox.isSelected() ^ editorSettings.isShowQuickDocOnMouseOverElement()) {
boolean enabled = myCbShowQuickDocOnCheckBox.isSelected();
editorSettings.setShowQuickDocOnMouseOverElement(enabled);
ServiceManager.getService(QuickDocOnMouseOverManager.class).setEnabled(enabled);
}
editorSettings.setDndEnabled(myCbEnableDnD.isSelected());
editorSettings.setWheelFontChangeEnabled(myCbEnableWheelFontChange.isSelected());
@@ -341,6 +351,7 @@ public class EditorOptionsPanel {
// Strip trailing spaces, ensure EOL on EOF on save
isModified |= !getStripTrailingSpacesValue().equals(editorSettings.getStripTrailingSpaces());
isModified |= isModified(myCbEnsureBlankLineBeforeCheckBox, editorSettings.isEnsureNewLineAtEOF());
isModified |= isModified(myCbShowQuickDocOnCheckBox, editorSettings.isShowQuickDocOnMouseOverElement());
// advanced mouse
isModified |= isModified(myCbEnableDnD, editorSettings.isDndEnabled());
@@ -155,7 +155,7 @@ public class FileReferenceQuickFixProvider {
FileTemplate template = FileTemplateManager.getInstance().getTemplate(templateName);
if (template != null) {
try {
return template.getText(FileTemplateManager.getInstance().getDefaultProperties());
return template.getText(FileTemplateManager.getInstance().getDefaultProperties(directory.getProject()));
} catch (IOException ex) {
throw new RuntimeException(ex);
}
@@ -146,7 +146,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
{
enableEvents(KeyEvent.KEY_EVENT_MASK);
enableEvents(AWTEvent.KEY_EVENT_MASK);
}
protected void processKeyEvent(KeyEvent e) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -154,7 +154,20 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
myUpdateDocAlarm = new Alarm(Alarm.ThreadToUse.OWN_THREAD,myProject);
}
public void showJavaDocInfo(@NotNull Editor editor,
@NotNull final PsiElement element,
@NotNull final PsiElement original,
@Nullable Runnable closeCallback)
{
myEditor = editor;
showJavaDocInfo(element, original, closeCallback);
}
public void showJavaDocInfo(@NotNull final PsiElement element, final PsiElement original) {
showJavaDocInfo(element, original, null);
}
public void showJavaDocInfo(@NotNull final PsiElement element, final PsiElement original, @Nullable Runnable closeCallback) {
PopupUpdateProcessor updateProcessor = new PopupUpdateProcessor(element.getProject()) {
public void updatePopup(Object lookupItemObject) {
if (lookupItemObject instanceof PsiElement) {
@@ -163,7 +176,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
};
doShowJavaDocInfo(element, false, updateProcessor, original, false);
doShowJavaDocInfo(element, false, updateProcessor, original, false, closeCallback);
}
public void showJavaDocInfo(final Editor editor, @Nullable final PsiFile file, boolean requestFocus) {
@@ -251,7 +264,18 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
private void doShowJavaDocInfo(final PsiElement element, boolean requestFocus, PopupUpdateProcessor updateProcessor,
final PsiElement originalElement, final boolean autoupdate) {
final PsiElement originalElement, final boolean autoupdate)
{
doShowJavaDocInfo(element, requestFocus, updateProcessor, originalElement, autoupdate, null);
}
private void doShowJavaDocInfo(final PsiElement element,
boolean requestFocus,
PopupUpdateProcessor updateProcessor,
final PsiElement originalElement,
final boolean autoupdate,
@Nullable final Runnable closeCallback)
{
Project project = getProject(element);
if (myToolWindow == null && PropertiesComponent.getInstance().isTrueValue(SHOW_DOCUMENTATION_IN_TOOL_WINDOW)) {
@@ -267,10 +291,12 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
fetchDocInfo(getDefaultCollector(element, originalElement), component, true);
if (!myToolWindow.isVisible()) myToolWindow.show(null);
return;
} else {
}
else {
if (element != null && !autoupdate) {
restorePopupBehavior();
} else {
}
else {
return;
}
}
@@ -289,7 +315,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
@Override
public void consume(PsiElement psiElement) {
final AbstractPopup jbPopup = (AbstractPopup)getDocInfoHint();
if(jbPopup != null) {
if (jbPopup != null) {
final String title = getTitle(psiElement, false);
jbPopup.setCaption(title);
}
@@ -304,7 +330,8 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
};
final KeyboardShortcut keyboardShortcut = ActionManagerEx.getInstanceEx().getKeyboardShortcut("QuickJavaDoc");
final List<Pair<ActionListener, KeyStroke>> actions = Collections.singletonList(Pair.<ActionListener, KeyStroke>create(new ActionListener() {
final List<Pair<ActionListener, KeyStroke>> actions =
Collections.singletonList(Pair.<ActionListener, KeyStroke>create(new ActionListener() {
public void actionPerformed(ActionEvent e) {
createToolWindow(element, originalElement);
final JBPopup hint = getDocInfoHint();
@@ -314,63 +341,66 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
boolean hasLookup = LookupManager.getActiveLookup(myEditor) != null;
final JBPopup hint = JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
.setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE)
.setProject(project)
.addListener(updateProcessor)
.addUserData(updateProcessor)
.setKeyboardActions(actions)
.setDimensionServiceKey(myProject, JAVADOC_LOCATION_AND_SIZE, false)
.setResizable(true)
.setMovable(true)
.setRequestFocus(requestFocus)
.setCancelOnClickOutside(!hasLookup) // otherwise selecting lookup items by mouse would close the doc
.setTitle(getTitle(element, false))
.setCouldPin(pinCallback)
.setCancelCallback(new Computable<Boolean>() {
public Boolean compute() {
if (fromQuickSearch()) {
((ChooseByNameBase.JPanelProvider)myPreviouslyFocused.getParent()).unregisterHint();
}
Disposer.dispose(component);
myEditor = null;
myPreviouslyFocused = null;
myParameterInfoController = null;
return Boolean.TRUE;
}
})
.createPopup();
AbstractPopup oldHint = (AbstractPopup)getDocInfoHint();
if (oldHint != null) {
DocumentationComponent oldComponent = (DocumentationComponent)oldHint.getComponent();
PsiElement element1 = oldComponent.getElement();
if (Comparing.equal(element, element1)) {
if (requestFocus) {
component.getComponent().requestFocus();
.setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE)
.setProject(project)
.addListener(updateProcessor)
.addUserData(updateProcessor)
.setKeyboardActions(actions)
.setDimensionServiceKey(myProject, JAVADOC_LOCATION_AND_SIZE, false)
.setResizable(true)
.setMovable(true)
.setRequestFocus(requestFocus)
.setCancelOnClickOutside(!hasLookup) // otherwise selecting lookup items by mouse would close the doc
.setTitle(getTitle(element, false))
.setCouldPin(pinCallback)
.setCancelCallback(new Computable<Boolean>() {
public Boolean compute() {
if (closeCallback != null) {
closeCallback.run();
}
return;
if (fromQuickSearch()) {
((ChooseByNameBase.JPanelProvider)myPreviouslyFocused.getParent()).unregisterHint();
}
Disposer.dispose(component);
myEditor = null;
myPreviouslyFocused = null;
myParameterInfoController = null;
return Boolean.TRUE;
}
oldHint.cancel();
})
.createPopup();
AbstractPopup oldHint = (AbstractPopup)getDocInfoHint();
if (oldHint != null) {
DocumentationComponent oldComponent = (DocumentationComponent)oldHint.getComponent();
PsiElement element1 = oldComponent.getElement();
if (Comparing.equal(element, element1)) {
if (requestFocus) {
component.getComponent().requestFocus();
}
return;
}
oldHint.cancel();
}
component.setHint(hint);
component.setHint(hint);
if (myEditor == null) {
// subsequent invocation of javadoc popup from completion will have myEditor == null because of cancel invoked,
// so reevaluate the editor for proper popup placement
Lookup lookup = LookupManager.getInstance(myProject).getActiveLookup();
myEditor = lookup != null ? lookup.getEditor() : null;
}
fetchDocInfo(getDefaultCollector(element, originalElement), component);
if (myEditor == null) {
// subsequent invocation of javadoc popup from completion will have myEditor == null because of cancel invoked,
// so reevaluate the editor for proper popup placement
Lookup lookup = LookupManager.getInstance(myProject).getActiveLookup();
myEditor = lookup != null ? lookup.getEditor() : null;
}
fetchDocInfo(getDefaultCollector(element, originalElement), component);
myDocInfoHintRef = new WeakReference<JBPopup>(hint);
myPreviouslyFocused = WindowManagerEx.getInstanceEx().getFocusedComponent(project);
myDocInfoHintRef = new WeakReference<JBPopup>(hint);
myPreviouslyFocused = WindowManagerEx.getInstanceEx().getFocusedComponent(project);
if (fromQuickSearch()) {
((ChooseByNameBase.JPanelProvider)myPreviouslyFocused.getParent()).registerHint(hint);
}
if (fromQuickSearch()) {
((ChooseByNameBase.JPanelProvider)myPreviouslyFocused.getParent()).registerHint(hint);
}
}
private static String getTitle(@NotNull final PsiElement element, final boolean _short) {
@@ -392,13 +422,19 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
@Nullable
public PsiElement findTargetElement(final Editor editor, @Nullable final PsiFile file, PsiElement contextElement) {
PsiElement element = editor != null ? TargetElementUtilBase.findTargetElement(editor, ourFlagsForTargetElements) : null;
return findTargetElement(editor, editor.getCaretModel().getOffset(), file, contextElement);
}
@Nullable
public PsiElement findTargetElement(final Editor editor, int offset, @Nullable final PsiFile file, PsiElement contextElement) {
TargetElementUtilBase util = TargetElementUtilBase.getInstance();
PsiElement element = editor != null ? util.findTargetElement(editor, ourFlagsForTargetElements, offset)
: null;
assertSameProject(element);
// Allow context doc over xml tag content
if (element != null || contextElement != null) {
final PsiElement adjusted = TargetElementUtilBase.getInstance()
.adjustElement(editor, ourFlagsForTargetElements, element, contextElement);
final PsiElement adjusted = util.adjustElement(editor, ourFlagsForTargetElements, element, contextElement);
if (adjusted != null) {
element = adjusted;
assertSameProject(element);
@@ -410,10 +446,10 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
assertSameProject(element);
if (element == null) {
final PsiReference ref = TargetElementUtilBase.findReference(editor, editor.getCaretModel().getOffset());
final PsiReference ref = util.findReference(editor, offset);
if (ref != null) {
element = TargetElementUtilBase.getInstance().adjustReference(ref);
element = util.adjustReference(ref);
assertSameProject(element);
if (element == null && ref instanceof PsiPolyVariantReference) {
element = ref.getElement();
@@ -0,0 +1,269 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.documentation;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.ui.popup.PopupFactoryImpl;
import com.intellij.util.Alarm;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
/**
* Serves as a facade to the 'show quick doc on mouse over an element' functionality.
* <p/>
* Not thread-safe.
*
* @author Denis Zhdanov
* @since 7/2/12 9:09 AM
*/
public class QuickDocOnMouseOverManager {
private static final long QUICK_DOC_DELAY_MILLIS;
static {
long delay = 500;
String property = System.getProperty("editor.auto.quick.doc.delay.ms");
if (property != null) {
try {
long parsed = Long.parseLong(property);
if (parsed > 0) {
delay = parsed;
}
}
catch (Exception e) {
// Ignore.
}
}
QUICK_DOC_DELAY_MILLIS = delay;
}
@NotNull private final EditorMouseMotionListener myEditorListener = new MyEditorMouseListener();
@NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
@NotNull private final Runnable myRequest = new MyShowQuickDocRequest();
@NotNull private final Runnable myHintCloseCallback = new Runnable() {
@Override
public void run() {
myActiveElements.clear();
myDocumentationManager = null;
}
};
private final Map<Editor, PsiElement /** PSI element which is located under the current mouse position */> myActiveElements
= new HashMap<Editor, PsiElement>();
/** Holds a reference (if any) to the documentation manager used last time to show an 'auto quick doc' popup. */
@Nullable private WeakReference<DocumentationManager> myDocumentationManager;
@Nullable private DelayedQuickDocInfo myDelayedQuickDocInfo;
private boolean myEnabled;
public QuickDocOnMouseOverManager(@NotNull Application application) {
EditorFactory factory = EditorFactory.getInstance();
if (factory != null) {
factory.addEditorFactoryListener(new MyEditorFactoryListener(), application);
}
}
/**
* Instructs the manager to enable or disable 'show quick doc automatically when the mouse goes over an editor element' mode.
*
* @param enabled flag that identifies if quick doc should be automatically shown
*/
public void setEnabled(boolean enabled) {
myEnabled = enabled;
if (!enabled) {
closeAutoQuickDocComponentIfNecessary();
myAlarm.cancelAllRequests();
}
EditorFactory factory = EditorFactory.getInstance();
if (factory == null) {
return;
}
for (Editor editor : factory.getAllEditors()) {
if (enabled) {
editor.addEditorMouseMotionListener(myEditorListener);
}
else {
editor.removeEditorMouseMotionListener(myEditorListener);
}
}
}
private void processMouseMove(@NotNull EditorMouseEvent e) {
if (e.getArea() != EditorMouseEventArea.EDITING_AREA) {
// Skip if the mouse is not at the editing area.
closeAutoQuickDocComponentIfNecessary();
return;
}
Editor editor = e.getEditor();
Project project = editor.getProject();
if (project == null) {
return;
}
DocumentationManager documentationManager = DocumentationManager.getInstance(project);
JBPopup hint = documentationManager.getDocInfoHint();
if (hint != null) {
// Skip the event if the control is shown because of explicit 'show quick doc' action call.
WeakReference<DocumentationManager> ref = myDocumentationManager;
if (ref == null || ref.get() == null) {
return;
}
// Skip the event if the mouse is under the opened quick doc control.
Point hintLocation = hint.getLocationOnScreen();
Dimension hintSize = hint.getSize();
int mouseX = e.getMouseEvent().getXOnScreen();
int mouseY = e.getMouseEvent().getYOnScreen();
if (mouseX >= hintLocation.x && mouseX <= hintLocation.x + hintSize.width && mouseY >= hintLocation.y
&& mouseY <= hintLocation.y + hintSize.height)
{
return;
}
}
PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
if (psiFile == null) {
closeAutoQuickDocComponentIfNecessary();
return;
}
int mouseOffset = editor.logicalPositionToOffset(editor.xyToLogicalPosition(e.getMouseEvent().getPoint()));
PsiElement elementUnderMouse = psiFile.findElementAt(mouseOffset);
if (elementUnderMouse == null || elementUnderMouse instanceof PsiWhiteSpace) {
closeAutoQuickDocComponentIfNecessary();
return;
}
PsiElement targetElementUnderMouse = documentationManager.findTargetElement(editor, mouseOffset, psiFile, elementUnderMouse);
if (targetElementUnderMouse == null) {
// No PSI element is located under the current mouse position - close quick doc if any.
closeAutoQuickDocComponentIfNecessary();
return;
}
PsiElement activeElement = myActiveElements.get(editor);
if (targetElementUnderMouse.equals(activeElement)
&& (myAlarm.getActiveRequestCount() > 0 // Request to show documentation for the target component has been already queued.
|| hint != null)) // Documentation for the target component is being shown.
{
return;
}
closeAutoQuickDocComponentIfNecessary();
myActiveElements.put(editor, targetElementUnderMouse);
myDelayedQuickDocInfo = new DelayedQuickDocInfo(documentationManager, editor, targetElementUnderMouse, elementUnderMouse);
myAlarm.cancelAllRequests();
myAlarm.addRequest(myRequest, QUICK_DOC_DELAY_MILLIS);
}
private void closeAutoQuickDocComponentIfNecessary() {
myAlarm.cancelAllRequests();
WeakReference<DocumentationManager> ref = myDocumentationManager;
if (ref == null) {
return;
}
DocumentationManager docManager = ref.get();
if (docManager == null) {
return;
}
JBPopup hint = docManager.getDocInfoHint();
if (hint == null) {
return;
}
hint.cancel();
}
private static class DelayedQuickDocInfo {
@NotNull public final DocumentationManager docManager;
@NotNull public final Editor editor;
@NotNull public final PsiElement targetElement;
@NotNull public final PsiElement originalElement;
private DelayedQuickDocInfo(@NotNull DocumentationManager docManager,
@NotNull Editor editor, @NotNull PsiElement targetElement,
@NotNull PsiElement originalElement)
{
this.docManager = docManager;
this.editor = editor;
this.targetElement = targetElement;
this.originalElement = originalElement;
}
}
private class MyShowQuickDocRequest implements Runnable {
@Override
public void run() {
myAlarm.cancelAllRequests();
DelayedQuickDocInfo info = myDelayedQuickDocInfo;
if (info == null || !info.targetElement.equals(myActiveElements.get(info.editor))) {
return;
}
info.editor.putUserData(PopupFactoryImpl.ANCHOR_POPUP_POSITION,
info.editor.offsetToVisualPosition(info.originalElement.getTextRange().getStartOffset()));
try {
info.docManager.showJavaDocInfo(info.editor, info.targetElement, info.originalElement, myHintCloseCallback);
myDocumentationManager = new WeakReference<DocumentationManager>(info.docManager);
}
finally {
info.editor.putUserData(PopupFactoryImpl.ANCHOR_POPUP_POSITION, null);
}
}
}
private class MyEditorFactoryListener implements EditorFactoryListener {
@Override
public void editorCreated(@NotNull EditorFactoryEvent event) {
if (myEnabled) {
event.getEditor().addEditorMouseMotionListener(myEditorListener);
}
}
@Override
public void editorReleased(@NotNull EditorFactoryEvent event) {
event.getEditor().removeEditorMouseMotionListener(myEditorListener);
}
}
private class MyEditorMouseListener extends EditorMouseMotionAdapter {
@Override
public void mouseMoved(EditorMouseEvent e) {
processMouseMove(e);
}
}
}
@@ -0,0 +1,35 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.documentation;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupActivity;
/**
* @author Denis Zhdanov
* @since 7/2/12 9:44 AM
*/
public class QuickDocOnMouseOverStartupActivity implements StartupActivity {
@Override
public void runActivity(Project project) {
if (EditorSettingsExternalizable.getInstance().isShowQuickDocOnMouseOverElement()) {
ServiceManager.getService(QuickDocOnMouseOverManager.class).setEnabled(true);
}
}
}
@@ -12,7 +12,6 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.util.text.CharArrayUtil;
@@ -21,7 +20,6 @@ import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.List;
/**
* @author yole
@@ -149,11 +147,7 @@ public class CopyPasteIndentProcessor implements CopyPastePostProcessor<IndentTr
EditorActionUtil.indentLine(project, editor, startLine, -value.getFirstLineLeadingSpaces());
}
final List<String> strings = StringUtil.split(pastedText, "\n");
//if (strings.get(strings.size() - 1))
if (strings.get(0).trim().startsWith("def") ||
strings.get(0).trim().startsWith("class")) endLine -=1;
if (caretColumn > value.getIndent()) endLine -=1;
for (int i = startLine+1; i <= endLine; i++) {
EditorActionUtil.indentLine(project, editor, i, value.getIndent());
@@ -244,9 +244,11 @@ public class LookupCellRenderer implements ListCellRenderer {
return getGrayedForeground(isSelected);
}
final Color tailForeground = presentation.getTailForeground();
if (tailForeground != null) {
return tailForeground;
if (!isSelected) {
final Color tailForeground = presentation.getTailForeground();
if (tailForeground != null) {
return tailForeground;
}
}
return defaultForeground;
@@ -362,8 +362,9 @@ public class ChooseRunConfigurationPopup {
return new ItemWrapper<RunnerAndConfigurationSettings>(settings) {
@Override
public void perform(@NotNull Project project, @NotNull Executor executor, @NotNull DataContext context) {
RunManagerEx.getInstanceEx(project).setSelectedConfiguration(getValue());
ProgramRunnerUtil.executeConfiguration(project, getValue(), executor);
RunnerAndConfigurationSettings config = getValue();
RunManagerEx.getInstanceEx(project).setSelectedConfiguration(config);
doRunConfiguration(config, executor, project);
}
@Override
@@ -470,7 +471,7 @@ public class ChooseRunConfigurationPopup {
@Override
public void perform(@NotNull final Project project, @NotNull final Executor executor, @NotNull DataContext context) {
ExecutionTargetManager.setActiveTarget(project, eachTarget);
ProgramRunnerUtil.executeConfiguration(project, selectedConfiguration, executor);
doRunConfiguration(selectedConfiguration, executor, project);
}
@Override
@@ -531,12 +532,7 @@ public class ChooseRunConfigurationPopup {
if (dialog.isOK()) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final RunnerAndConfigurationSettings configuration = RunManager.getInstance(project).getSelectedConfiguration();
if (configuration instanceof RunnerAndConfigurationSettingsImpl) {
if (canRun(executor, configuration)) {
ProgramRunnerUtil.executeConfiguration(project, configuration, executor);
}
}
doRunConfiguration(RunManager.getInstance(project).getSelectedConfiguration(), executor, project);
}
});
}
@@ -616,7 +612,7 @@ public class ChooseRunConfigurationPopup {
public void perform(@NotNull Project project, @NotNull Executor executor, @NotNull DataContext context) {
manager.setTemporaryConfiguration(configuration);
RunManagerEx.getInstanceEx(project).setSelectedConfiguration(configuration);
ProgramRunnerUtil.executeConfiguration(project, configuration, executor);
doRunConfiguration(configuration, executor, project);
}
@Override
@@ -729,6 +725,14 @@ public class ChooseRunConfigurationPopup {
}
}
private static void doRunConfiguration(RunnerAndConfigurationSettings configuration, Executor executor, Project project) {
if (configuration instanceof RunnerAndConfigurationSettingsImpl) {
if (canRun(executor, configuration)) {
ProgramRunnerUtil.executeConfiguration(project, configuration, executor);
}
}
}
private static final class ConfigurationActionsStep extends BaseListPopupStep<ActionWrapper> {
private ConfigurationActionsStep(@NotNull final Project project,
ChooseRunConfigurationPopup action,
@@ -761,7 +765,7 @@ public class ChooseRunConfigurationPopup {
manager.setSelectedConfiguration(settings);
ExecutionTargetManager.setActiveTarget(project, eachTarget);
ProgramRunnerUtil.executeConfiguration(project, settings, action.getCurrentExecutor(), eachTarget);
doRunConfiguration(settings, action.getCurrentExecutor(), project);
}
});
}
@@ -776,7 +780,7 @@ public class ChooseRunConfigurationPopup {
final RunManagerEx manager = RunManagerEx.getInstanceEx(project);
if (dynamic) manager.setTemporaryConfiguration(settings);
manager.setSelectedConfiguration(settings);
ProgramRunnerUtil.executeConfiguration(project, settings, executor);
doRunConfiguration(settings, executor, project);
}
});
isFirst = false;
@@ -280,7 +280,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
EmptyAction.registerActionShortcuts(myHistoryViewer.getComponent(), myConsoleEditor.getComponent());
}
private boolean isFullEditorMode() {
public boolean isFullEditorMode() {
return myPanel.getComponentCount() == 1;
}
@@ -232,6 +232,7 @@ public class GridCellImpl implements GridCell {
return info.
setIcon(content.getIcon()).
setText(content.getDisplayName()).
setTooltipText(content.getDescription()).
setActionsContextComponent(content.getActionsContextComponent()).
setActions(content.getActions(), content.getPlace());
}
@@ -20,6 +20,7 @@ import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
@@ -42,23 +43,24 @@ public abstract class CreateFileFromTemplateAction extends CreateFromTemplateAct
protected PsiFile createFileFromTemplate(String name, FileTemplate template, PsiDirectory dir) {
PsiElement element;
Project project = dir.getProject();
try {
element = FileTemplateUtil
.createFromTemplate(template, name, FileTemplateManager.getInstance().getDefaultProperties(), dir);
.createFromTemplate(template, name, FileTemplateManager.getInstance().getDefaultProperties(project), dir);
final PsiFile psiFile = element.getContainingFile();
final VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile != null) {
FileEditorManager.getInstance(dir.getProject()).openFile(virtualFile, true);
FileEditorManager.getInstance(project).openFile(virtualFile, true);
String property = getDefaultTemplateProperty();
if (property != null) {
PropertiesComponent.getInstance(dir.getProject()).setValue(property, template.getName());
PropertiesComponent.getInstance(project).setValue(property, template.getName());
}
return psiFile;
}
}
catch (ParseException e) {
Messages.showErrorDialog(dir.getProject(), "Error parsing Velocity template: " + e.getMessage(), "Create File from Template");
Messages.showErrorDialog(project, "Error parsing Velocity template: " + e.getMessage(), "Create File from Template");
return null;
}
catch (IncorrectOperationException e) {
@@ -17,6 +17,7 @@
package com.intellij.ide.fileTemplates;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -59,6 +60,13 @@ public abstract class FileTemplateManager{
@NotNull
public abstract Properties getDefaultProperties();
@NotNull
public Properties getDefaultProperties(Project project) {
Properties properties = getDefaultProperties();
properties.setProperty("PROJECT_NAME", project.getName());
return properties;
}
/**
* Creates a new template with specified name.
* @param name
@@ -266,7 +266,7 @@ public class FileTemplateUtil{
@Nullable ClassLoader classLoader) throws Exception {
@NotNull final Project project = directory.getProject();
if (props == null) {
props = FileTemplateManager.getInstance().getDefaultProperties();
props = FileTemplateManager.getInstance().getDefaultProperties(directory.getProject());
}
FileTemplateManager.getInstance().addRecentName(template.getName());
fillDefaultProperties(props, directory);
@@ -357,7 +357,7 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
if (fileType == FileTypes.UNKNOWN) return null;
final PsiFile file = PsiFileFactory.getInstance(myProject).createFileFromText(name + ".txt.ft", fileType, text, 0, true);
file.getViewProvider().putUserData(FileTemplateManager.DEFAULT_TEMPLATE_PROPERTIES, FileTemplateManager.getInstance().getDefaultProperties());
file.getViewProvider().putUserData(FileTemplateManager.DEFAULT_TEMPLATE_PROPERTIES, FileTemplateManager.getInstance().getDefaultProperties(myProject));
return file;
}
@@ -57,7 +57,7 @@ public class CreateFromTemplateDialog extends DialogWrapper {
myTemplate = template;
setTitle(IdeBundle.message("title.new.from.template", template.getName()));
myDefaultProperties = defaultProperties == null ? FileTemplateManager.getInstance().getDefaultProperties() : defaultProperties;
myDefaultProperties = defaultProperties == null ? FileTemplateManager.getInstance().getDefaultProperties(project) : defaultProperties;
FileTemplateUtil.fillDefaultProperties(myDefaultProperties, directory);
boolean mustEnterName = FileTemplateUtil.findHandler(template).isNameRequired();
if (attributesDefaults != null && attributesDefaults.isFixedName()) {
@@ -580,7 +580,7 @@ public class SingleInspectionProfilePanel extends JPanel {
}
static String renderSeverity(HighlightSeverity severity) {
return severity.toString().toLowerCase();
return StringUtil.capitalizeWords(severity.toString().toLowerCase(), true);
}
private void toggleToolNode(final InspectionConfigTreeNode toolNode) {
@@ -124,7 +124,7 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager impleme
public void startRunInjectors(@NotNull final Document hostDocument, final boolean synchronously) {
if (myProject.isDisposed()) return;
assert synchronously || !ApplicationManager.getApplication().isWriteAccessAllowed();
if (!synchronously && ApplicationManager.getApplication().isWriteAccessAllowed()) return;
// use cached to avoid recreate PSI in alien project
final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
final PsiFile hostPsiFile = documentManager.getCachedPsiFile(hostDocument);
@@ -19,6 +19,7 @@ package com.intellij.tools;
import com.intellij.ide.macro.MacroManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.project.DumbAware;
/**
@@ -34,11 +35,15 @@ public class ToolAction extends AnAction implements DumbAware {
}
public void actionPerformed(AnActionEvent e) {
MacroManager.getInstance().cacheMacrosPreview(e.getDataContext());
final HackyDataContext dataContext = new HackyDataContext(e.getDataContext());
runTool(myActionId, e.getDataContext());
}
static void runTool(String actionId, DataContext context) {
MacroManager.getInstance().cacheMacrosPreview(context);
final HackyDataContext dataContext = new HackyDataContext(context);
Tool[] tools = ToolManager.getInstance().getTools();
for (Tool tool : tools) {
if (myActionId.equals(tool.getActionId())) {
if (actionId.equals(tool.getActionId())) {
tool.execute(dataContext);
break;
}
@@ -0,0 +1,88 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tools;
import com.intellij.execution.BeforeRunTask;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.util.ui.UIUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
public class ToolBeforeRunTask extends BeforeRunTask<ToolBeforeRunTask> {
@NonNls private final static String ACTION_ID_ATTRIBUTE = "actionId";
private String myToolActionId;
protected ToolBeforeRunTask() {
super(ToolBeforeRunTaskProvider.ID);
}
@Nullable
public String getToolActionId() {
return myToolActionId;
}
public void setToolActionId(String toolActionId) {
myToolActionId = toolActionId;
}
public boolean isExecutable() {
return myToolActionId != null;
}
@Override
public void writeExternal(Element element) {
super.writeExternal(element);
if (myToolActionId != null) {
element.setAttribute(ACTION_ID_ATTRIBUTE, myToolActionId);
}
}
@Override
public void readExternal(Element element) {
super.readExternal(element);
myToolActionId = element.getAttributeValue(ACTION_ID_ATTRIBUTE);
}
@Override
public ToolBeforeRunTask clone() {
return (ToolBeforeRunTask)super.clone();
}
public void execute(final DataContext context) {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
ToolAction.runTool(myToolActionId, context);
}
});
}
@Nullable
public Tool findCorrespondingTool() {
if (myToolActionId == null) {
return null;
}
Tool[] tools = ToolManager.getInstance().getTools();
for (Tool tool : tools) {
if (myToolActionId.equals(tool.getActionId())) {
return tool;
}
}
return null;
}
}
@@ -0,0 +1,105 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tools;
import com.intellij.execution.BeforeRunTaskProvider;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
public class ToolBeforeRunTaskProvider extends BeforeRunTaskProvider<ToolBeforeRunTask> {
static final Key<ToolBeforeRunTask> ID = Key.create("ToolBeforeRunTask");
private static final Logger LOG = Logger.getInstance("#" + ToolBeforeRunTaskProvider.class.getName());
@Override
public Key<ToolBeforeRunTask> getId() {
return ID;
}
@Override
public String getName() {
return ToolsBundle.message("tools.before.run.provider.name");
}
@Override
public String getDescription(ToolBeforeRunTask task) {
final String actionId = task.getToolActionId();
if (actionId == null) {
LOG.error("Null id");
return ToolsBundle.message("tools.unknown.external.tool");
}
Tool tool = task.findCorrespondingTool();
if (tool == null) {
return ToolsBundle.message("tools.unknown.external.tool");
}
String groupName = tool.getGroup();
return ToolsBundle
.message("tools.before.run.description", StringUtil.isEmpty(groupName) ? tool.getName() : groupName + "/" + tool.getName());
}
/*
@Override //todo[lene]
public Icon getIcon() {
return ICON;
}*/
@Override
public boolean isConfigurable() {
return true;
}
@Override
public ToolBeforeRunTask createTask(RunConfiguration runConfiguration) {
return new ToolBeforeRunTask();
}
@Override
public boolean configureTask(RunConfiguration runConfiguration, ToolBeforeRunTask task) {
final ToolSelectDialog dialog = new ToolSelectDialog(runConfiguration.getProject(), task);
dialog.show();
if (!dialog.isOK()) {
return false;
}
boolean isModified = dialog.isModified();
Tool selectedTool = dialog.getSelectedTool();
LOG.assertTrue(selectedTool != null);
String selectedToolId = selectedTool.getActionId();
String oldToolId = task.getToolActionId();
if (oldToolId != null && oldToolId.equals(selectedToolId)) {
return isModified;
}
task.setToolActionId(selectedToolId);
return true;
}
@Override
public boolean canExecuteTask(RunConfiguration configuration, ToolBeforeRunTask task) {
return task.isExecutable();
}
@Override
public boolean executeTask(DataContext context, RunConfiguration configuration, ExecutionEnvironment env, ToolBeforeRunTask task) {
if (!task.isExecutable()) {
return false;
}
task.execute(context);
return true;
}
}
@@ -0,0 +1,83 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tools;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.awt.RelativePoint;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import java.awt.*;
import java.io.IOException;
class ToolSelectDialog extends DialogWrapper {
private final ToolsPanel myToolsPanel = new ToolsPanel();
protected ToolSelectDialog(@Nullable Project project, ToolBeforeRunTask task) {
super(project);
myToolsPanel.reset();
myToolsPanel.addSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent e) {
final Tool selectedTool = myToolsPanel.getSingleSelectedTool();
boolean isOk = selectedTool != null;
setOKActionEnabled(isOk);
}
});
init();
pack();
if(task.getToolActionId() != null){
myToolsPanel.selectTool(task.getToolActionId());
}
}
@Override
protected void doOKAction() {
try {
myToolsPanel.apply();
}
catch (IOException e) {
String message = ToolsBundle.message("tools.failed.to.save.changes.0", StringUtil.decapitalize(e.getMessage()));
final JLayeredPane pane = myToolsPanel.getRootPane().getLayeredPane();
JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(message, MessageType.ERROR, null)
.setShowCallout(false).setFadeoutTime(3000).setHideOnAction(true).setHideOnClickOutside(true).setHideOnKeyOutside(true).
createBalloon().show(new RelativePoint(pane, new Point(pane.getWidth(), 0)), Balloon.Position.above);
return;
}
super.doOKAction();
}
@Override
protected JComponent createCenterPanel() {
return myToolsPanel;
}
@Nullable
Tool getSelectedTool() {
return myToolsPanel.getSingleSelectedTool();
}
boolean isModified() {
return myToolsPanel.isModified();
}
}
@@ -33,6 +33,7 @@ import javax.swing.tree.*;
import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
class ToolsPanel extends JPanel {
static enum Direction {
@@ -488,4 +489,52 @@ class ToolsPanel extends JPanel {
}
return ArrayUtil.toStringArray(result);
}
void addSelectionListener(TreeSelectionListener listener) {
myTree.getSelectionModel().addTreeSelectionListener(listener);
}
@Nullable
Tool getSingleSelectedTool() {
final TreePath[] selectionPaths = myTree.getSelectionPaths();
if (selectionPaths == null || selectionPaths.length != 1) {
return null;
}
Object toolOrToolGroup = ((CheckedTreeNode)selectionPaths[0].getLastPathComponent()).getUserObject();
if (toolOrToolGroup instanceof Tool) {
return (Tool)toolOrToolGroup;
}
return null;
}
public void selectTool(final String actionId) {
Object root = myTree.getModel().getRoot();
if (root == null || !(root instanceof CheckedTreeNode)) {
return;
}
final List<CheckedTreeNode> nodes = new ArrayList<CheckedTreeNode>();
new Object() {
@SuppressWarnings("unchecked")
public void collect(CheckedTreeNode node) {
if (node.isLeaf()) {
Object userObject = node.getUserObject();
if (userObject instanceof Tool && actionId.equals(((Tool)userObject).getActionId())) {
nodes.add(node);
}
}
else {
for (int i = 0; i < node.getChildCount(); i++) {
final TreeNode child = node.getChildAt(i);
if (child instanceof CheckedTreeNode) {
collect((CheckedTreeNode)child);
}
}
}
}
}.collect((CheckedTreeNode)root);
if (nodes.isEmpty()) {
return;
}
myTree.getSelectionModel().setSelectionPath(new TreePath(nodes.get(0).getPath()));
}
}
@@ -50,13 +50,15 @@ public class IndexingStamp {
private Timestamps(@Nullable DataInputStream stream) throws IOException {
if (stream != null) {
try {
long dominatingIndexStamp = DataInputOutputUtil.readTIME(stream);
while(stream.available() > 0) {
ID<?, ?> id = ID.findById(DataInputOutputUtil.readINT(stream));
if (id != null) {
long stamp = IndexInfrastructure.getIndexCreationStamp(id);
if (myIndexStamps == null) myIndexStamps = new TObjectLongHashMap<ID<?, ?>>(5, 0.98f);
if (stamp <= dominatingIndexStamp) myIndexStamps.put(id, stamp);
if (stream.available() > 0) {
long dominatingIndexStamp = DataInputOutputUtil.readTIME(stream);
while(stream.available() > 0) {
ID<?, ?> id = ID.findById(DataInputOutputUtil.readINT(stream));
if (id != null) {
long stamp = IndexInfrastructure.getIndexCreationStamp(id);
if (myIndexStamps == null) myIndexStamps = new TObjectLongHashMap<ID<?, ?>>(5, 0.98f);
if (stamp <= dominatingIndexStamp) myIndexStamps.put(id, stamp);
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@ public abstract class EditorFactory implements ApplicationComponent {
*
* @return the editor factory instance.
*/
@Nullable
public static EditorFactory getInstance() {
final Application application = ApplicationManager.getApplication();
return application == null ? null : application.getComponent(EditorFactory.class);
@@ -168,7 +169,7 @@ public abstract class EditorFactory implements ApplicationComponent {
/**
* Registers a listener for receiving notifications when editor instances are created and released
* and removes the listener when {@link parentDisposable} get disposed.
* and removes the listener when the <code>'parentDisposable'</code> gets disposed.
*
* @param listener the listener instance.
* @param parentDisposable the Disposable which triggers the removal of the listener
@@ -176,7 +177,7 @@ public abstract class EditorFactory implements ApplicationComponent {
public abstract void addEditorFactoryListener(@NotNull EditorFactoryListener listener, @NotNull Disposable parentDisposable);
/**
* Unregisters a listener for receiving notifications when editor instances are created
* Un-registers a listener for receiving notifications when editor instances are created
* and released.
*
* @param listener the listener instance.
@@ -215,7 +215,7 @@ public class OpenFileDescriptor implements Navigatable {
}
}
private void unfoldCurrentLine(@NotNull final Editor editor) {
private static void unfoldCurrentLine(@NotNull final Editor editor) {
final FoldRegion[] allRegions = editor.getFoldingModel().getAllFoldRegions();
final int offset = editor.getCaretModel().getOffset();
int line = editor.getDocument().getLineNumber(offset);
@@ -226,7 +226,7 @@ public class OpenFileDescriptor implements Navigatable {
@Override
public void run() {
for (FoldRegion region : allRegions) {
if (!region.isExpanded() && range.intersects(TextRange.create(region))) /*region.getStartOffset() <= offset && offset <= region.getEndOffset()*/ {
if (!region.isExpanded() && range.intersects(TextRange.create(region))) {
region.setExpanded(true);
}
}
@@ -240,14 +240,15 @@ public class OpenFileDescriptor implements Navigatable {
@Override
public boolean canNavigate() {
return myProject != null;
return myFile.isValid();
}
@Override
public boolean canNavigateToSource() {
return myProject != null;
return canNavigate();
}
@NotNull
public Project getProject() {
return myProject;
}
@@ -814,7 +814,7 @@ public class Messages {
textField.setText(textArea.getText());
}
});
String s = textField.getText().replaceAll("[ ]*=[ ]*", "=").replaceAll("\\-", "\\ \\-");
String s = textField.getText().replaceAll("[ ]*=[ ]*", "=").replaceAll("=\\-", "=\\ \\-");
List<String> lines = StringUtil.splitHonorQuotes(s, ' ');
textArea.setText(StringUtil.join(lines, "\n"));
InsertPathAction.copyFromTo(textField, textArea);
@@ -0,0 +1,23 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util;
/**
* @deprecated use {@link PlatformIcons} for generic icons and corresponding classes from plugins for plugin-specific icons
* @see PlatformIcons
*/
public abstract class Icons implements PlatformIcons {
}
@@ -149,12 +149,11 @@ public class ShowFeatureUsageStatisticsDialog extends DialogWrapper {
long idleTime = app.getIdleTime();
final String uptimeS = FeatureStatisticsBundle.message("feature.statistics.application.uptime",
ApplicationNamesInfo.getInstance().getProductName(),
ApplicationNamesInfo.getInstance().getFullProductName(),
DateFormatUtil.formatDuration(uptime));
final String idleTimeS = FeatureStatisticsBundle .message("feature.statistics.application.idle.time",
ApplicationNamesInfo.getInstance().getProductName(),
DateFormatUtil.formatDuration(idleTime));
final String idleTimeS = FeatureStatisticsBundle.message("feature.statistics.application.idle.time",
DateFormatUtil.formatDuration(idleTime));
String labelText = uptimeS + ", " + idleTimeS;
CompletionStatistics stats = ((FeatureUsageTrackerImpl)FeatureUsageTracker.getInstance()).getCompletionStatistics();
@@ -25,6 +25,7 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
import java.awt.event.InputEvent;
import java.io.File;
/**
* @author yole
@@ -50,8 +51,9 @@ public class ReopenProjectAction extends AnAction implements DumbAware {
final int modifiers = e.getModifiers();
final boolean forceOpenInNewFrame = (modifiers & InputEvent.CTRL_MASK) != 0 || (modifiers & InputEvent.SHIFT_MASK) != 0;
Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
if (!RecentProjectsManagerBase.isValidProjectPath(myProjectPath)) {
Messages.showErrorDialog(project, "The project path " + FileUtil.toSystemDependentName(myProjectPath) + " does not exist.\n" +
File file = new File(myProjectPath);
if (!file.exists() || !file.isDirectory()) {
Messages.showErrorDialog(project, "The directory " + FileUtil.toSystemDependentName(myProjectPath) + " does not exist.\n" +
"If it is on a removable or network drive, please make sure that the drive is connected.",
"Reopen Project");
return;
@@ -70,6 +70,7 @@ public class CustomActionsSchema implements ExportableComponent, NamedJDOMExtern
myIdToNameList.add(new Pair(IdeActions.GROUP_EDITOR_GUTTER, "Editor Gutter Popup Menu"));
myIdToNameList.add(new Pair(IdeActions.GROUP_EDITOR_TAB_POPUP, ActionsTreeUtil.EDITOR_TAB_POPUP));
myIdToNameList.add(new Pair(IdeActions.GROUP_PROJECT_VIEW_POPUP, ActionsTreeUtil.PROJECT_VIEW_POPUP));
myIdToNameList.add(new Pair(IdeActions.GROUP_SCOPE_VIEW_POPUP, "Scope View Popup Menu"));
myIdToNameList.add(new Pair(IdeActions.GROUP_FAVORITES_VIEW_POPUP, ActionsTreeUtil.FAVORITES_POPUP));
myIdToNameList.add(new Pair(IdeActions.GROUP_COMMANDER_POPUP, ActionsTreeUtil.COMMANDER_POPUP));
myIdToNameList.add(new Pair(IdeActions.GROUP_J2EE_VIEW_POPUP, ActionsTreeUtil.J2EE_POPUP));
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.ExportableApplicationComponent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
@@ -50,6 +51,7 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex
public boolean IS_CARET_INSIDE_TABS;
@NonNls public String STRIP_TRAILING_SPACES = "Changed";
public boolean IS_ENSURE_NEWLINE_AT_EOF = false;
public boolean SHOW_QUICK_DOC_ON_MOUSE_OVER_ELEMENT = false;
public boolean IS_CARET_BLINKING = true;
public int CARET_BLINKING_PERIOD = 500;
public boolean IS_RIGHT_MARGIN_SHOWN = true;
@@ -356,7 +358,7 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex
public void setEnsureNewLineAtEOF(boolean ensure) {
myOptions.IS_ENSURE_NEWLINE_AT_EOF = ensure;
}
public String getStripTrailingSpaces() {
return myOptions.STRIP_TRAILING_SPACES;
} // TODO: move to CodeEditorManager or something else
@@ -365,6 +367,14 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex
myOptions.STRIP_TRAILING_SPACES = stripTrailingSpaces;
}
public boolean isShowQuickDocOnMouseOverElement() {
return myOptions.SHOW_QUICK_DOC_ON_MOUSE_OVER_ELEMENT;
}
public void setShowQuickDocOnMouseOverElement(boolean show) {
myOptions.SHOW_QUICK_DOC_ON_MOUSE_OVER_ELEMENT = show;
}
public boolean isRefrainFromScrolling() {
return myOptions.REFRAIN_FROM_SCROLLING;
}
@@ -2508,7 +2508,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
@NotNull Rectangle clip,
@NotNull LogicalPosition clipStartPosition,
int clipStartOffset,
int clipEndOffset) {
int clipEndOffset)
{
myCurrentFontType = null;
myLastCache = null;
final int plainSpaceWidth = EditorUtil.getSpaceWidth(Font.PLAIN, this);
@@ -323,16 +323,17 @@ abstract class FoldRegionsTree {
}
public int getLastTopLevelIndexBefore(int offset) {
if (!isFoldingEnabledAndUpToDate()) return -1;
int[] endOffsets = myCachedEndOffsets;
if (!isFoldingEnabledAndUpToDate() || endOffsets == null) return -1;
int start = 0;
int end = myCachedEndOffsets.length - 1;
int end = endOffsets.length - 1;
while (start <= end) {
int i = (start + end) / 2;
if (offset < myCachedEndOffsets[i]) {
if (offset < endOffsets[i]) {
end = i - 1;
} else if (offset > myCachedEndOffsets[i]) {
} else if (offset > endOffsets[i]) {
start = i + 1;
}
else {
@@ -589,6 +589,7 @@ public class SoftWrapApplianceManager implements SoftWrapFoldingListener, Docume
myContext.currentPosition.offset--;
myContext.currentPosition.logicalColumn -= columnsDiff;
myContext.currentPosition.visualColumn -= columnsDiff;
myContext.currentPosition.x -= pixelsDiff;
}
}
}
@@ -899,6 +900,10 @@ public class SoftWrapApplianceManager implements SoftWrapFoldingListener, Docume
return myListeners.add(listener);
}
public boolean removeListener(@NotNull SoftWrapAwareDocumentParsingListener listener) {
return myListeners.remove(listener);
}
@SuppressWarnings({"ForLoopReplaceableByForEach"})
private void revertListeners(int offset, int visualLine) {
for (int i = 0; i < myListeners.size(); i++) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ import org.jetbrains.annotations.NotNull;
* @author Denis Zhdanov
* @since 11/23/11 7:04 PM
*/
public class SoftWrapAwareDocumentParsingListenerAdapter implements SoftWrapAwareDocumentParsingListener {
public abstract class SoftWrapAwareDocumentParsingListenerAdapter implements SoftWrapAwareDocumentParsingListener {
@Override
public void onVisualLineStart(@NotNull EditorPosition position) {
}
@@ -823,7 +823,7 @@ public class FSRecords implements Forceable {
}
}
public static void updateList(int id, int[] children) {
public static void updateList(int id, @NotNull int[] children) {
try {
w.lock();
DbConnection.markDirty();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.VisualPosition;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.*;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@ import com.intellij.openapi.ui.popup.*;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
@@ -65,6 +66,14 @@ import java.util.HashMap;
import java.util.List;
public class PopupFactoryImpl extends JBPopupFactory {
/**
* Allows to get an editor position for which a popup with auxiliary information might be shown.
* <p/>
* Primary intention for this key is to hint popup position for the non-caret location.
*/
public static final Key<VisualPosition> ANCHOR_POPUP_POSITION = Key.create("popup.anchor.position");
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.popup.PopupFactoryImpl");
private static final Icon QUICK_LIST_ICON = AllIcons.Actions.QuickList;
@@ -78,7 +87,7 @@ public class PopupFactoryImpl extends JBPopupFactory {
}
public JBPopup createMessage(String text) {
return createListPopup(new BaseListPopupStep<String>(null, new String[]{text}));
return createListPopup(new BaseListPopupStep<String>(null, new String[]{text}));
}
@Override
@@ -98,28 +107,34 @@ public class PopupFactoryImpl extends JBPopupFactory {
return null;
}
public ListPopup createConfirmation(String title, final String yesText, String noText, final Runnable onYes, final Runnable onNo, int defaultOptionIndex) {
public ListPopup createConfirmation(String title,
final String yesText,
String noText,
final Runnable onYes,
final Runnable onNo,
int defaultOptionIndex)
{
final BaseListPopupStep<String> step = new BaseListPopupStep<String>(title, new String[]{yesText, noText}) {
public PopupStep onChosen(String selectedValue, final boolean finalChoice) {
if (selectedValue.equals(yesText)) {
onYes.run();
}
else {
onNo.run();
}
return FINAL_CHOICE;
final BaseListPopupStep<String> step = new BaseListPopupStep<String>(title, new String[]{yesText, noText}) {
public PopupStep onChosen(String selectedValue, final boolean finalChoice) {
if (selectedValue.equals(yesText)) {
onYes.run();
}
public void canceled() {
else {
onNo.run();
}
return FINAL_CHOICE;
}
public boolean isMnemonicsNavigationEnabled() {
return true;
}
};
step.setDefaultOptionIndex(defaultOptionIndex);
public void canceled() {
onNo.run();
}
public boolean isMnemonicsNavigationEnabled() {
return true;
}
};
step.setDefaultOptionIndex(defaultOptionIndex);
final ApplicationEx app = ApplicationManagerEx.getApplicationEx();
return app == null || !app.isUnitTestMode() ? new ListPopupImpl(step) : new MockConfirmation(step, yesText);
@@ -127,13 +142,13 @@ public class PopupFactoryImpl extends JBPopupFactory {
private static ListPopup createActionGroupPopup(final String title,
final ActionGroup actionGroup,
@NotNull DataContext dataContext,
boolean showNumbers,
boolean useAlphaAsNumbers,
boolean showDisabledActions,
boolean honorActionMnemonics,
final Runnable disposeCallback,
final ActionGroup actionGroup,
@NotNull DataContext dataContext,
boolean showNumbers,
boolean useAlphaAsNumbers,
boolean showDisabledActions,
boolean honorActionMnemonics,
final Runnable disposeCallback,
final int maxRowCount) {
return createActionGroupPopup(title, actionGroup, dataContext, showNumbers, useAlphaAsNumbers, showDisabledActions, honorActionMnemonics, disposeCallback,
maxRowCount, null, null);
@@ -458,14 +473,18 @@ public class PopupFactoryImpl extends JBPopupFactory {
}
public RelativePoint guessBestPopupLocation(Editor editor) {
CaretModel caretModel = editor.getCaretModel();
final VisualPosition visualPosition;
if (caretModel.isUpToDate()) {
visualPosition = caretModel.getVisualPosition();
}
else {
visualPosition = editor.offsetToVisualPosition(caretModel.getOffset());
VisualPosition visualPosition = editor.getUserData(ANCHOR_POPUP_POSITION);
if (visualPosition == null) {
CaretModel caretModel = editor.getCaretModel();
if (caretModel.isUpToDate()) {
visualPosition = caretModel.getVisualPosition();
}
else {
visualPosition = editor.offsetToVisualPosition(caretModel.getOffset());
}
}
Point p = editor.visualPositionToXY(new VisualPosition(visualPosition.line + 1, visualPosition.column));
final Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
@@ -372,6 +372,7 @@ checkbox.show.virtual.space.at.file.bottom=Show virtual space at file bottom
checkbox.optimize.imports.on.the.fly=Optimize imports on the fly
checkbox.add.unambiguous.imports.on.the.fly=Add unambiguous imports on the fly
combobox.strip.trailing.spaces.on.save=Strip trailing spaces on Save:
checkbox.show.quick.doc.on.mouse.over=Show quick doc on mouse over element
group.limits=Limits
editbox.recent.files.limit=Recent files limit:
editbox.console.history.limit=Console commands history size:
@@ -24,7 +24,7 @@ feature.statistics.not.applicable=N/A
# {0} - application name (IntelliJ IDEA or Visual Fabrique or RubyMine or WebStorm or PhpStorm or PyCharm or CIDR)
# {1} - formatted duration.
feature.statistics.application.uptime={0} uptime: {1}
feature.statistics.application.idle.time={0} idle time: {1}
feature.statistics.application.idle.time=idle time: {0}
# Names of features in the feature statistics bundle
navigation.popup.class=Go to class
@@ -50,4 +50,8 @@ tools.delete.confirmation=Do you want to delete the external tool(s)?
tools.name.column=Name
tools.group.column=Group
tools.description.column=Description
tools.not.configured=No external tools configured
tools.not.configured=No external tools configured
tools.unknown.external.tool=Unknown external tool
tools.before.run.description=External tool ''{0}''
tools.failed.to.save.changes.0=Failed to save changes: {0}
tools.before.run.provider.name=Run External tool
@@ -362,6 +362,7 @@
<!-- External Tools -->
<applicationConfigurable instance="com.intellij.tools.ToolConfigurable"/>
<stepsBeforeRunProvider implementation="com.intellij.tools.ToolBeforeRunTaskProvider"/>
<lang.parserDefinition language="TEXT" implementationClass="com.intellij.openapi.fileTypes.PlainTextParserDefinition"/>
<lang.syntaxHighlighterFactory key="TEXT" implementationClass="com.intellij.openapi.fileTypes.PlainTextSyntaxHighlighterFactory"/>
@@ -733,7 +734,10 @@
<applicationService serviceInterface="com.intellij.ide.todo.TodoConfiguration"
serviceImplementation="com.intellij.ide.todo.TodoConfiguration"/>
<indexPatternProvider implementation="com.intellij.ide.todo.TodoIndexPatternProvider"/>
<applicationService serviceImplementation="com.intellij.codeInsight.documentation.QuickDocOnMouseOverManager"/>
<postStartupActivity implementation="com.intellij.codeInsight.documentation.QuickDocOnMouseOverStartupActivity"/>
<hectorComponentProvider implementation="com.intellij.codeInsight.daemon.PowerSaveHectorProvider"/>
<copyPastePostProcessor implementation="com.intellij.codeInsight.editorActions.CopyPasteIndentProcessor"/>
@@ -17,8 +17,12 @@ package com.intellij.openapi.editor.impl.softwrap.mapping;
import com.intellij.codeInsight.folding.CodeFoldingManager;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.impl.*;
import com.intellij.openapi.editor.impl.AbstractEditorProcessingOnDocumentModificationTest;
import com.intellij.openapi.editor.impl.DefaultEditorTextRepresentationHelper;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.testFramework.TestFileType;
import gnu.trove.TIntHashSet;
@@ -994,9 +998,37 @@ public class SoftWrapApplianceOnDocumentModificationTest extends AbstractEditorP
assertEquals(text.substring(0, text.indexOf("line")) + text.substring(text.indexOf('9')), myEditor.getDocument().getText());
assertEquals(position, caretModel.getVisualPosition());
}
public void testNoUnnecessaryHorizontalScrollBar() throws IOException {
// Inspired by IDEA-87184
final String text = "12345678 abcdefgh";
init(15, 7, text);
myEditor.getCaretModel().moveToOffset(text.length());
final Ref<Boolean> fail = new Ref<Boolean>(true);
SoftWrapApplianceManager applianceManager = ((SoftWrapModelImpl)myEditor.getSoftWrapModel()).getApplianceManager();
SoftWrapAwareDocumentParsingListener listener = new SoftWrapAwareDocumentParsingListenerAdapter() {
@Override
public void beforeSoftWrapLineFeed(@NotNull EditorPosition position) {
if (position.x == text.indexOf("a") * 7) {
fail.set(false);
}
}
};
applianceManager.addListener(listener);
try {
backspace();
}
finally {
applianceManager.removeListener(listener);
}
assertFalse(fail.get());
}
private void init(final int visibleWidthInColumns, @NotNull String fileText) throws IOException {
int symbolWidthInPixels = 7;
init(visibleWidthInColumns, 7, fileText);
}
private void init(final int visibleWidthInColumns, final int symbolWidthInPixels, @NotNull String fileText) throws IOException {
init(visibleWidthInColumns * symbolWidthInPixels, fileText, symbolWidthInPixels);
}
@@ -588,14 +588,13 @@ public class DirectoryIndexImpl extends DirectoryIndex {
}
protected void fillMapWithOrderEntries(final VirtualFile root,
final Collection<OrderEntry> orderEntries,
@NotNull final Collection<OrderEntry> orderEntries,
@Nullable final Module module,
@Nullable final VirtualFile libraryClassRoot,
@Nullable final VirtualFile librarySourceRoot,
@Nullable final DirectoryInfo parentInfo, @Nullable final ProgressIndicator progress) {
VfsUtilCore.visitChildrenRecursively(root, new DirectoryVisitor() {
private final Stack<List<OrderEntry>> myEntries = new Stack<List<OrderEntry>>();
@Override
@@ -21,6 +21,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -80,12 +81,13 @@ public class DirectoryInfo {
"}";
}
@NotNull
public List<OrderEntry> getOrderEntries() {
return orderEntries == null ? Collections.<OrderEntry>emptyList() : orderEntries;
}
@SuppressWarnings({"unchecked"})
public void addOrderEntries(Collection<OrderEntry> orderEntries,
public void addOrderEntries(@NotNull Collection<OrderEntry> orderEntries,
@Nullable final DirectoryInfo parentInfo,
@Nullable final List<OrderEntry> oldParentEntries) {
if (orderEntries.isEmpty()) {
@@ -16,6 +16,8 @@
package com.intellij.openapi.util;
import com.intellij.openapi.util.text.StringUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collection;
@@ -28,24 +30,22 @@ import java.util.Set;
public class Comparing {
private Comparing() { }
public static <T> boolean equal(T arg1, T arg2){
public static <T> boolean equal(@Nullable T arg1, @Nullable T arg2){
if (arg1 == null || arg2 == null){
return arg1 == arg2;
}
else if (arg1 instanceof Object[] && arg2 instanceof Object[]){
if (arg1 instanceof Object[] && arg2 instanceof Object[]){
Object[] arr1 = (Object[])arg1;
Object[] arr2 = (Object[])arg2;
return Arrays.equals(arr1, arr2);
}
else if (arg1 instanceof CharSequence && arg2 instanceof CharSequence) {
if (arg1 instanceof CharSequence && arg2 instanceof CharSequence) {
return equal((CharSequence)arg1, (CharSequence)arg2, true);
}
else{
return arg1.equals(arg2);
}
return arg1.equals(arg2);
}
public static <T> boolean equal(T[] arr1, T[] arr2){
public static <T> boolean equal(@Nullable T[] arr1, @Nullable T[] arr2){
if (arr1 == null || arr2 == null){
return arr1 == arr2;
}
@@ -60,7 +60,7 @@ public class Comparing {
return equal(arg1, arg2, true);
}
public static boolean equal(CharSequence s1, CharSequence s2, boolean caseSensitive) {
public static boolean equal(@Nullable CharSequence s1, @Nullable CharSequence s2, boolean caseSensitive) {
if (s1 == s2) return true;
if (s1 == null || s2 == null) return false;
@@ -84,7 +84,7 @@ public class Comparing {
return true;
}
public static boolean equal(String arg1, String arg2, boolean caseSensitive){
public static boolean equal(@Nullable String arg1, @Nullable String arg2, boolean caseSensitive){
if (arg1 == null || arg2 == null){
return arg1 == arg2;
}
@@ -97,11 +97,11 @@ public class Comparing {
return strEqual(arg1, arg2, true);
}
public static boolean strEqual(String arg1, String arg2, boolean caseSensitive){
public static boolean strEqual(@Nullable String arg1, @Nullable String arg2, boolean caseSensitive){
return equal(arg1 == null ? "" : arg1, arg2 == null ? "" : arg2, caseSensitive);
}
public static <T> boolean haveEqualElements(Collection<T> a, Collection<T> b) {
public static <T> boolean haveEqualElements(@NotNull Collection<T> a, @NotNull Collection<T> b) {
if (a.size() != b.size()) {
return false;
}
@@ -115,7 +115,7 @@ public class Comparing {
return true;
}
public static <T> boolean haveEqualElements(T[] a, T[] b) {
public static <T> boolean haveEqualElements(@Nullable T[] a, @Nullable T[] b) {
if (a == null || b == null) {
return a == b;
}
@@ -133,7 +133,7 @@ public class Comparing {
return true;
}
public static int hashcode(Object obj) { return obj == null ? 0 : obj.hashCode(); }
public static int hashcode(@Nullable Object obj) { return obj == null ? 0 : obj.hashCode(); }
public static int hashcode(Object obj1, Object obj2) { return hashcode(obj1) ^ hashcode(obj2); }
public static int compare(byte o1, byte o2) {
@@ -152,7 +152,7 @@ public class Comparing {
return o1 < o2 ? -1 : o1 == o2 ? 0 : 1;
}
public static int compare(byte[] o1, byte[] o2) {
public static int compare(@Nullable byte[] o1, @Nullable byte[] o2) {
if (o1 == o2) return 0;
if (o1 == null) return 1;
if (o2 == null) return -1;
@@ -167,7 +167,7 @@ public class Comparing {
return 0;
}
public static <T extends Comparable<T>> int compare(final T o1, final T o2) {
public static <T extends Comparable<T>> int compare(@Nullable final T o1, @Nullable final T o2) {
if (o1 == null) return o2 == null ? 0 : -1;
if (o2 == null) return 1;
return o1.compareTo(o2);
@@ -15,6 +15,7 @@
*/
package com.intellij.execution.process;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.Processor;
@@ -45,6 +46,8 @@ public class UnixProcessManager {
}
}
catch (Exception e) {
Logger log = Logger.getInstance(UnixProcessManager.class);
log.warn("Can't load c library", e);
C_LIB = null;
}
}
@@ -1331,6 +1331,9 @@ public class StringUtil extends StringUtilRt {
return value.indexOf(ch) >= 0;
}
/**
* @deprecated use #capitalize(String)
*/
@Nullable
public static String firstLetterToUpperCase(@Nullable final String displayString) {
if (displayString == null || displayString.isEmpty()) return displayString;
@@ -1658,13 +1661,11 @@ public class StringUtil extends StringUtilRt {
@NonNls private static final String[] REPLACES_REFS = {"&lt;", "&gt;", "&amp;", "&#39;", "&quot;"};
@NonNls private static final String[] REPLACES_DISP = {"<", ">", "&", "'", "\""};
@Nullable
public static String unescapeXml(@Nullable final String text) {
if (text == null) return null;
return replace(text, REPLACES_REFS, REPLACES_DISP);
}
@Nullable
public static String escapeXml(@Nullable final String text) {
if (text == null) return null;
return replace(text, REPLACES_DISP, REPLACES_REFS);
@@ -18,6 +18,7 @@ package com.intellij.util.containers;
import com.intellij.util.ConcurrencyUtil;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.Serializable;
@@ -592,6 +593,7 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
}
// inherit Map javadoc
@Override
public boolean isEmpty() {
final Segment[] segments = this.segments;
/*
@@ -625,6 +627,7 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
}
// inherit Map javadoc
@Override
public int size() {
final Segment[] segments = this.segments;
long sum = 0;
@@ -678,6 +681,7 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
* @throws NullPointerException if the key is
* <tt>null</tt>.
*/
@Override
public V get(Object key) {
int hash = myHashingStrategy.computeHashCode((K)key); // throws NullPointerException if key null
return segmentFor(hash).get((K)key, hash);
@@ -693,6 +697,7 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
* @throws NullPointerException if the key is
* <tt>null</tt>.
*/
@Override
public boolean containsKey(Object key) {
int hash = myHashingStrategy.computeHashCode((K)key); // throws NullPointerException if key null
return segmentFor(hash).containsKey((K)key, hash);
@@ -709,9 +714,8 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
* specified value.
* @throws NullPointerException if the value is <tt>null</tt>.
*/
public boolean containsValue(Object value) {
if (value == null)
throw new NullPointerException();
@Override
public boolean containsValue(@NotNull Object value) {
// See explanation of modCount use above
@@ -793,9 +797,8 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
* @throws NullPointerException if the key or value is
* <tt>null</tt>.
*/
public V put(K key, V value) {
if (value == null)
throw new NullPointerException();
@Override
public V put(K key, @NotNull V value) {
int hash = myHashingStrategy.computeHashCode(key);
return segmentFor(hash).put(key, hash, value, false);
}
@@ -818,9 +821,8 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
* @throws NullPointerException if the specified key or value is
* <tt>null</tt>.
*/
public V putIfAbsent(K key, V value) {
if (value == null)
throw new NullPointerException();
@Override
public V putIfAbsent(@NotNull K key, @NotNull V value) {
int hash = myHashingStrategy.computeHashCode(key);
return segmentFor(hash).put(key, hash, value, true);
}
@@ -834,6 +836,7 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
*
* @param t Mappings to be stored in this map.
*/
@Override
public void putAll(Map<? extends K, ? extends V> t) {
for (Iterator<? extends Entry<? extends K, ? extends V>> it = (Iterator<? extends Entry<? extends K, ? extends V>>) t.entrySet().iterator(); it.hasNext(); ) {
Entry<? extends K, ? extends V> e = it.next();
@@ -851,6 +854,7 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
* @throws NullPointerException if the key is
* <tt>null</tt>.
*/
@Override
public V remove(Object key) {
int hash = myHashingStrategy.computeHashCode((K)key);
return segmentFor(hash).remove((K)key, hash, null);
@@ -872,7 +876,8 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
* @throws NullPointerException if the specified key is
* <tt>null</tt>.
*/
public boolean remove(Object key, Object value) {
@Override
public boolean remove(@NotNull Object key, Object value) {
int hash = myHashingStrategy.computeHashCode((K)key);
return segmentFor(hash).remove((K)key, hash, value) != null;
}
@@ -895,9 +900,8 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
* @throws NullPointerException if the specified key or values are
* <tt>null</tt>.
*/
public boolean replace(K key, V oldValue, V newValue) {
if (oldValue == null || newValue == null)
throw new NullPointerException();
@Override
public boolean replace(@NotNull K key, @NotNull V oldValue, @NotNull V newValue) {
int hash = myHashingStrategy.computeHashCode(key);
return segmentFor(hash).replace(key, hash, oldValue, newValue);
}
@@ -918,9 +922,8 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
* @throws NullPointerException if the specified key or value is
* <tt>null</tt>.
*/
public V replace(K key, V value) {
if (value == null)
throw new NullPointerException();
@Override
public V replace(@NotNull K key, @NotNull V value) {
int hash = myHashingStrategy.computeHashCode(key);
return segmentFor(hash).replace(key, hash, value);
}
@@ -929,9 +932,9 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
/**
* Removes all mappings from this map.
*/
@Override
public void clear() {
for (int i = 0; i < segments.length; ++i)
segments[i].clear();
for (Segment segment : segments) segment.clear();
}
/**
@@ -950,6 +953,7 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
*
* @return a set view of the keys contained in this map.
*/
@Override
public Set<K> keySet() {
Set<K> ks = keySet;
return (ks != null) ? ks : (keySet = new KeySet());
@@ -972,6 +976,7 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
*
* @return a collection view of the values contained in this map.
*/
@Override
public Collection<V> values() {
Collection<V> vs = values;
return (vs != null) ? vs : (values = new Values());
@@ -995,6 +1000,7 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
*
* @return a collection view of the mappings contained in this map.
*/
@Override
public Set<Entry<K,V>> entrySet() {
Set<Entry<K,V>> es = entrySet;
return (es != null) ? es : (entrySet = (Set<Entry<K,V>>) (Set) new EntrySet());
@@ -1080,12 +1086,16 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
}
final class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> {
@Override
public K next() { return super.nextEntry().key; }
@Override
public K nextElement() { return super.nextEntry().key; }
}
final class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> {
@Override
public V next() { return super.nextEntry().value; }
@Override
public V nextElement() { return super.nextEntry().value; }
}
@@ -1098,23 +1108,27 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
* itself acts as a forwarding pseudo-entry.
*/
final class EntryIterator extends HashIterator implements Entry<K,V>, Iterator<Entry<K,V>> {
@Override
public Entry<K,V> next() {
nextEntry();
return this;
}
@Override
public K getKey() {
if (lastReturned == null)
throw new IllegalStateException("Entry was removed");
return lastReturned.key;
}
@Override
public V getValue() {
if (lastReturned == null)
throw new IllegalStateException("Entry was removed");
return ConcurrentHashMap.this.get(lastReturned.key);
}
@Override
public V setValue(V value) {
if (lastReturned == null)
throw new IllegalStateException("Entry was removed");
@@ -1159,27 +1173,34 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
}
final class KeySet extends AbstractSet<K> {
@Override
public Iterator<K> iterator() {
return new KeyIterator();
}
@Override
public int size() {
return ConcurrentHashMap.this.size();
}
@Override
public boolean contains(Object o) {
return ConcurrentHashMap.this.containsKey(o);
}
@Override
public boolean remove(Object o) {
return ConcurrentHashMap.this.remove(o) != null;
}
@Override
public void clear() {
ConcurrentHashMap.this.clear();
}
@Override
public Object[] toArray() {
Collection<K> c = new ArrayList<K>();
for (Iterator<K> i = iterator(); i.hasNext(); )
c.add(i.next());
return c.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
Collection<K> c = new ArrayList<K>();
for (Iterator<K> i = iterator(); i.hasNext(); )
@@ -1189,24 +1210,30 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
}
final class Values extends AbstractCollection<V> {
@Override
public Iterator<V> iterator() {
return new ValueIterator();
}
@Override
public int size() {
return ConcurrentHashMap.this.size();
}
@Override
public boolean contains(Object o) {
return ConcurrentHashMap.this.containsValue(o);
}
@Override
public void clear() {
ConcurrentHashMap.this.clear();
}
@Override
public Object[] toArray() {
Collection<V> c = new ArrayList<V>();
for (Iterator<V> i = iterator(); i.hasNext(); )
c.add(i.next());
return c.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
Collection<V> c = new ArrayList<V>();
for (Iterator<V> i = iterator(); i.hasNext(); )
@@ -1216,9 +1243,11 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
}
final class EntrySet extends AbstractSet<Entry<K,V>> {
@Override
public Iterator<Entry<K,V>> iterator() {
return new EntryIterator();
}
@Override
public boolean contains(Object o) {
if (!(o instanceof Entry))
return false;
@@ -1226,18 +1255,22 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
V v = ConcurrentHashMap.this.get(e.getKey());
return v != null && v.equals(e.getValue());
}
@Override
public boolean remove(Object o) {
if (!(o instanceof Entry))
return false;
Entry<K,V> e = (Entry<K,V>)o;
return ConcurrentHashMap.this.remove(e.getKey(), e.getValue());
}
@Override
public int size() {
return ConcurrentHashMap.this.size();
}
@Override
public void clear() {
ConcurrentHashMap.this.clear();
}
@Override
public Object[] toArray() {
// Since we don't ordinarily have distinct Entry objects, we
// must pack elements using exportable SimpleEntry
@@ -1246,6 +1279,7 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
c.add(new SimpleEntry(i.next()));
return c.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
Collection<Entry<K,V>> c = new ArrayList<Entry<K,V>>(size());
for (Iterator<Entry<K,V>> i = iterator(); i.hasNext(); )
@@ -1273,14 +1307,17 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
this.value = e.getValue();
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
@Override
public V setValue(V value) {
V oldValue = this.value;
this.value = value;
@@ -1368,6 +1405,7 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
}
}
@Override
public int computeHashCode(final K object) {
int h = object.hashCode();
h += ~(h << 9);
@@ -1377,6 +1415,7 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements Concur
return h;
}
@Override
public boolean equals(final K o1, final K o2) {
return o1.equals(o2);
}
@@ -38,14 +38,14 @@ public class StringSearcher {
}
public StringSearcher(@NotNull String pattern, boolean caseSensitive, boolean forwardDirection) {
LOG.assertTrue(pattern.length() > 0);
LOG.assertTrue(!pattern.isEmpty());
myPattern = pattern;
myCaseSensitive = caseSensitive;
myForwardDirection = forwardDirection;
myPatternArray = myCaseSensitive ? myPattern.toCharArray() : myPattern.toLowerCase().toCharArray();
myPatternLength = myPatternArray.length;
Arrays.fill(mySearchTable, -1);
myJavaIdentifier = pattern.length() == 0 ||
myJavaIdentifier = pattern.isEmpty() ||
Character.isJavaIdentifierPart(pattern.charAt(0)) &&
Character.isJavaIdentifierPart(pattern.charAt(pattern.length() - 1));
}
@@ -40,7 +40,9 @@ public class AndroidDesignerBundle {
private static ResourceBundle getBundle() {
ResourceBundle bundle = null;
if (ourBundle != null) bundle = ourBundle.get();
if (ourBundle != null) {
bundle = ourBundle.get();
}
if (bundle == null) {
bundle = ResourceBundle.getBundle(BUNDLE);
ourBundle = new SoftReference<ResourceBundle>(bundle);
@@ -31,6 +31,7 @@ import com.intellij.designer.designSurface.selection.NonResizeSelectionDecorator
import com.intellij.designer.designSurface.tools.ComponentCreationFactory;
import com.intellij.designer.designSurface.tools.ComponentPasteFactory;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.model.WrapInProvider;
import com.intellij.designer.palette.DefaultPaletteItem;
import com.intellij.designer.palette.PaletteGroup;
import com.intellij.designer.palette.PaletteItem;
@@ -77,6 +78,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel {
private volatile RenderSession mySession;
private boolean myParseTime;
private int myProfileLastVersion;
private WrapInProvider myWrapInProvider;
public AndroidDesignerEditorPanel(@NotNull DesignerEditor editor,
@NotNull Project project,
@@ -464,6 +466,14 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel {
return myTreeDecorator;
}
@Override
public WrapInProvider getWrapInProvider() {
if (myWrapInProvider == null) {
myWrapInProvider = new AndroidWrapInProvider(getProject());
}
return myWrapInProvider;
}
private static final ComponentDecorator NON_RESIZE_DECORATOR = new NonResizeSelectionDecorator(Color.RED, 2);
@Override
@@ -0,0 +1,48 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.android.designer.model;
import com.intellij.designer.model.MetaModel;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.model.WrapInProvider;
import com.intellij.openapi.project.Project;
import java.util.List;
/**
* @author Alexander Lobas
*/
public final class AndroidWrapInProvider extends WrapInProvider<RadViewComponent> {
public AndroidWrapInProvider(Project project) {
super(ViewsMetaManager.getInstance(project));
}
@Override
public RadComponent wrapIn(RadViewComponent parent, List<RadViewComponent> components, MetaModel target) throws Exception {
RadViewComponent newParent = ModelParser.createComponent(null, target);
ModelParser.addComponent(parent, newParent, components.get(0));
for (RadViewComponent component : components) {
ModelParser.moveComponent(newParent, component, null);
}
RadViewLayout layout = (RadViewLayout)parent.getLayout();
layout.wrapIn(newParent, components);
return newParent;
}
}
@@ -43,4 +43,7 @@ public class RadViewLayout extends RadLayout {
JComponent shortcuts,
List<RadComponent> selection) {
}
public void wrapIn(RadViewComponent newParent, List<RadViewComponent> components) throws Exception {
}
}
@@ -21,6 +21,7 @@ import com.intellij.android.designer.designSurface.layout.actions.LayoutMarginOp
import com.intellij.android.designer.designSurface.layout.actions.LayoutWeightOperation;
import com.intellij.android.designer.designSurface.layout.actions.ResizeOperation;
import com.intellij.android.designer.designSurface.layout.flow.FlowStaticDecorator;
import com.intellij.android.designer.model.ModelParser;
import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.android.designer.model.RadViewLayoutWithData;
import com.intellij.android.designer.model.layout.actions.AbstractGravityAction;
@@ -34,6 +35,7 @@ import com.intellij.designer.model.RadComponent;
import com.intellij.designer.utils.Position;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
@@ -280,4 +282,71 @@ public class RadLinearLayout extends RadViewLayoutWithData implements ILayoutDec
actionGroup.add(new OrientationAction(designer, components, horizontal, override));
}
@Override
public boolean isWrapIn(List<RadComponent> components) {
List<RadComponent> children = myContainer.getChildren();
int[] indexes = new int[components.size()];
for (int i = 0; i < indexes.length; i++) {
indexes[i] = children.indexOf(components.get(i));
}
Arrays.sort(indexes);
for (int i = 0; i < indexes.length - 1; i++) {
if (indexes[i + 1] - indexes[i] != 1) {
return false;
}
}
return true;
}
@Override
public void wrapIn(final RadViewComponent newParent, final List<RadViewComponent> components) throws Exception {
final boolean horizontal = isHorizontal();
RadViewComponent firstComponent = components.get(0);
boolean single = components.size() == 1;
String layoutWidth = single ? firstComponent.getTag().getAttributeValue("android:layout_width") : "wrap_content";
String layoutHeight = single ? firstComponent.getTag().getAttributeValue("android:layout_height") : "wrap_content";
String layoutGravity = firstComponent.getTag().getAttributeValue("android:layout_gravity");
if (horizontal) {
for (RadViewComponent component : components.subList(1, components.size())) {
String height = component.getTag().getAttributeValue("android:layout_height");
if ("fill_parent".equals(height) || "match_parent".equals(height)) {
layoutHeight = "fill_parent";
layoutGravity = null;
}
if (layoutGravity != null && layoutGravity.equals(component.getTag().getAttributeValue("android:layout_gravity"))) {
}
}
}
else {
}
if (newParent.getLayout() instanceof RadLinearLayout) {
RadLinearLayout layout = (RadLinearLayout)newParent.getLayout();
if (horizontal != layout.isHorizontal()) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
newParent.getTag().setAttribute("android:orientation", horizontal ? "horizontal" : "vertical");
}
});
}
}
else {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
for (RadViewComponent component : components) {
ModelParser.deleteAttribute(component.getTag(), "android:layout_gravity");
}
}
});
}
}
}
@@ -1447,6 +1447,15 @@
</creation>
</meta>
<wrap-in>
<item tag="FrameLayout"/>
<item tag="LinearLayout"/>
<item tag="TableLayout"/>
<item tag="TableRow"/>
<item tag="GridLayout"/>
<item tag="RelativeLayout"/>
</wrap-in>
<!-- ================= Palette ================= -->
<palette>
@@ -210,7 +210,7 @@ public class ResourceDialog extends DialogWrapper implements TreeSelectionListen
}
}
myExtractStyleAction.getTemplatePresentation().setEnabled(enabled);
actionGroup.add(myExtractStyleAction);
//actionGroup.add(myExtractStyleAction); // XXX
}
return actionManager.createActionPopupMenu(ActionPlaces.UNKNOWN, actionGroup);
@@ -366,7 +366,7 @@ public class ResourceDialog extends DialogWrapper implements TreeSelectionListen
myResultResourceName = prefix + element.getName();
}
panel.showPreview(element, isProjectPanel);
//panel.showPreview(element, isProjectPanel); // XXX
}
}
@@ -447,7 +447,7 @@ public class ResourceDialog extends DialogWrapper implements TreeSelectionListen
myComponent.add(ScrollPaneFactory.createScrollPane(myTree), BorderLayout.CENTER);
myPreviewPanel = new JPanel(new CardLayout());
myComponent.add(myPreviewPanel, BorderLayout.SOUTH);
//myComponent.add(myPreviewPanel, BorderLayout.SOUTH); // XXX
myTextArea = new JTextArea(5, 20);
myPreviewPanel.add(ScrollPaneFactory.createScrollPane(myTextArea), TEXT);
@@ -84,18 +84,18 @@ public class AndroidFileTemplateProvider implements FileTemplateGroupDescriptorF
@NotNull VirtualFile rootDir,
@NotNull String templateName,
@NotNull String fileName) throws Exception {
return createFromTemplate(project, rootDir, templateName, fileName, FileTemplateManager.getInstance().getDefaultProperties());
return createFromTemplate(project, rootDir, templateName, fileName, FileTemplateManager.getInstance().getDefaultProperties(project));
}
public static PsiElement createFromTemplate(String templateName, String fileName, PsiDirectory directory, Properties properties)
public static PsiElement createFromTemplate(String templateName, String fileName, @NotNull PsiDirectory directory, Properties properties)
throws Exception {
FileTemplateManager manager = FileTemplateManager.getInstance();
FileTemplate template = manager.getJ2eeTemplate(templateName);
return FileTemplateUtil.createFromTemplate(template, fileName, properties, directory);
}
public static PsiElement createFromTemplate(String templateName, String fileName, PsiDirectory directory) throws Exception {
return createFromTemplate(templateName, fileName, directory, FileTemplateManager.getInstance().getDefaultProperties());
public static PsiElement createFromTemplate(String templateName, String fileName, @NotNull PsiDirectory directory) throws Exception {
return createFromTemplate(templateName, fileName, directory, FileTemplateManager.getInstance().getDefaultProperties(directory.getProject()));
}
@NotNull
@@ -459,7 +459,7 @@ public class AndroidModuleBuilder extends JavaModuleBuilder {
return;
}
Properties properties = FileTemplateManager.getInstance().getDefaultProperties();
Properties properties = FileTemplateManager.getInstance().getDefaultProperties(project);
properties.setProperty("TARGET", platform.getTarget().hashString());
AndroidFileTemplateProvider.createFromTemplate(project, contentRoot, AndroidFileTemplateProvider.DEFAULT_PROPERTIES_TEMPLATE,
SdkConstants.FN_PROJECT_PROPERTIES, properties);
@@ -69,7 +69,7 @@ public class GitVcsSettings implements PersistentStateComponent<GitVcsSettings.S
public SshExecutable SSH_EXECUTABLE = SshExecutable.IDEA_SSH;
public UpdateChangesPolicy UPDATE_CHANGES_POLICY = UpdateChangesPolicy.STASH; // The policy that specifies how files are saved before update or rebase
public UpdateMethod UPDATE_TYPE = UpdateMethod.BRANCH_DEFAULT;
public ConversionPolicy LINE_SEPARATORS_CONVERSION = ConversionPolicy.CONVERT;
public ConversionPolicy LINE_SEPARATORS_CONVERSION = ConversionPolicy.ASK;
public boolean PUSH_AUTO_UPDATE = false;
public GitBranchSyncSetting SYNC_SETTING = GitBranchSyncSetting.NOT_DECIDED;
public String RECENT_GIT_ROOT_PATH = null;
@@ -32,6 +32,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.tasks.github.GithubApiUtil;
import git4idea.GitVcs;
import git4idea.Notificator;
import org.jetbrains.annotations.NotNull;
@@ -162,7 +163,7 @@ public class GithubCreateGistAction extends DumbAwareAction {
}
String requestBody = prepareJsonRequest(description, isPrivate, text, file);
try {
JsonElement jsonElement = GithubUtil.postRequest("https://api.github.com", login, password, "/gists", requestBody);
JsonElement jsonElement = GithubApiUtil.postRequest("https://api.github.com", login, password, "/gists", requestBody);
if (jsonElement == null) {
LOG.info("Null JSON response returned by GitHub");
showError(project, "Failed to create gist", "Empty JSON response returned by GitHub", null, null);
@@ -27,6 +27,7 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.tasks.github.GithubApiUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
@@ -42,8 +43,6 @@ import org.jetbrains.annotations.NotNull;
)
public class GithubSettings implements PersistentStateComponent<Element> {
public static final String DEFAULT_GITHUB_HOST = "github.com";
private static final String GITHUB_SETTINGS_TAG = "GithubSettings";
private static final String LOGIN = "Login";
private static final String HOST = "Host";
@@ -154,7 +153,7 @@ public class GithubSettings implements PersistentStateComponent<Element> {
}
public String getHost() {
return myHost != null ? myHost : DEFAULT_GITHUB_HOST;
return myHost != null ? myHost : GithubApiUtil.DEFAULT_GITHUB_HOST;
}
public boolean isAnonymous() {
@@ -187,7 +186,7 @@ public class GithubSettings implements PersistentStateComponent<Element> {
}
public void setHost(final String host) {
myHost = host != null ? host : DEFAULT_GITHUB_HOST;
myHost = host != null ? host : GithubApiUtil.DEFAULT_GITHUB_HOST;
}
public void setAnonymousGist(final boolean anonymousGist) {
@@ -39,6 +39,7 @@ import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
import com.intellij.openapi.vcs.changes.InvokeAfterUpdateMode;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.tasks.github.GithubApiUtil;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.containers.HashSet;
import git4idea.GitDeprecatedRemote;
@@ -161,7 +162,7 @@ public class GithubShareAction extends DumbAwareAction {
@NotNull String description, boolean aPrivate) throws IOException {
String path = "/user/repos";
String requestBody = prepareRequest(name, description, aPrivate);
JsonElement result = GithubUtil.postRequest(host, login, password, path, requestBody);
JsonElement result = GithubApiUtil.postRequest(host, login, password, path, requestBody);
if (result == null) {
return false;
}
@@ -17,8 +17,6 @@ package org.jetbrains.plugins.github;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -30,19 +28,12 @@ import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.net.HttpConfigurable;
import com.intellij.tasks.github.GithubApiUtil;
import git4idea.config.GitVcsApplicationSettings;
import git4idea.config.GitVersion;
import git4idea.i18n.GitBundle;
import git4idea.repo.GitRemote;
import git4idea.repo.GitRepository;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.ui.GithubLoginDialog;
@@ -68,7 +59,7 @@ public class GithubUtil {
static final String GITHUB_NOTIFICATION_GROUP = "github";
/**
* @deprecated The host may be defined in different formats. Use {@link #getApiUrl(String)} instead.
* @deprecated The host may be defined in different formats. Use {@link com.intellij.tasks.github.GithubApiUtil#getApiUrl(String)} instead.
*/
@Deprecated
public static String getHttpsUrl() {
@@ -101,132 +92,6 @@ public class GithubUtil {
});
}
@Nullable
public static JsonElement getRequest(@NotNull String host, @NotNull String login, @NotNull String password,
@NotNull String path) throws IOException {
return request(host, login, password, path, null, false);
}
@Nullable
public static JsonElement postRequest(@NotNull String host, @Nullable String login, @Nullable String password,
@NotNull String path, @Nullable String requestBody) throws IOException {
return request(host, login, password, path, requestBody, true);
}
@Nullable
private static JsonElement request(@NotNull String host, @Nullable String login, @Nullable String password,
@NotNull String path, @Nullable String requestBody, boolean post) throws IOException {
HttpMethod method = null;
try {
method = doREST(host, login, password, path, requestBody, post);
String resp = method.getResponseBodyAsString();
if (resp == null) {
LOG.info(String.format("Unexpectedly empty response: %s", resp));
return null;
}
return parseResponse(resp);
}
finally {
if (method != null) {
method.releaseConnection();
}
}
}
@NotNull
private static HttpMethod doREST(@NotNull String host, @Nullable String login, @Nullable String password, @NotNull String path,
@Nullable String requestBody, final boolean post) throws IOException {
final HttpClient client = getHttpClient(login, password);
final String uri = getApiUrl(host) + path;
final HttpMethod method;
if (post) {
method = new PostMethod(uri);
if (requestBody != null) {
((PostMethod)method).setRequestEntity(new StringRequestEntity(requestBody, "application/json", "UTF-8"));
}
}
else {
method = new GetMethod(uri);
}
client.executeMethod(method);
return method;
}
@NotNull
private static String removeProtocolPrefix(final String url) {
if (url.startsWith("https://")) {
return url.substring(8);
}
else if (url.startsWith("http://")) {
return url.substring(7);
}
else if (url.startsWith("git@")) {
return url.substring(4);
}
else {
return url;
}
}
@NotNull
private static String getApiUrl(@NotNull String urlFromSettings) {
return "https://" + getApiUrlWithoutProtocol(urlFromSettings);
}
/*
All API access is over HTTPS, and accessed from the api.github.com domain
(or through yourdomain.com/api/v3/ for enterprise).
http://developer.github.com/v3/
*/
@NotNull
private static String getApiUrlWithoutProtocol(String urlFromSettings) {
String url = removeTrailingSlash(removeProtocolPrefix(urlFromSettings));
final String API_PREFIX = "api.";
final String ENTERPRISE_API_SUFFIX = "/api/v3";
if (url.equals(GithubSettings.DEFAULT_GITHUB_HOST)) {
return API_PREFIX + url;
}
else if (url.equals(API_PREFIX + GithubSettings.DEFAULT_GITHUB_HOST)) {
return url;
}
else if (url.endsWith(ENTERPRISE_API_SUFFIX)) {
return url;
}
else {
return url + ENTERPRISE_API_SUFFIX;
}
}
private static String removeTrailingSlash(String s) {
if (s.endsWith("/")) {
return s.substring(0, s.length() - 1);
}
return s;
}
@NotNull
private static HttpClient getHttpClient(@Nullable final String login, @Nullable final String password) {
final HttpClient client = new HttpClient();
client.getParams().setContentCharset("UTF-8");
// Configure proxySettings if it is required
final HttpConfigurable proxySettings = HttpConfigurable.getInstance();
if (proxySettings.USE_HTTP_PROXY){
client.getHostConfiguration().setProxy(proxySettings.PROXY_HOST, proxySettings.PROXY_PORT);
if (proxySettings.PROXY_AUTHENTICATION) {
client.getState().setProxyCredentials(AuthScope.ANY, new UsernamePasswordCredentials(proxySettings.PROXY_LOGIN,
proxySettings.getPlainProxyPassword()));
}
}
if (login != null && password != null) {
client.getParams().setCredentialCharset("UTF-8");
client.getParams().setAuthenticationPreemptive(true);
client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(login, password));
}
return client;
}
private static boolean testConnection(final String url, final String login, final String password) {
GithubUser user = retrieveCurrentUserInfo(url, login, password);
return user != null;
@@ -235,7 +100,7 @@ public class GithubUtil {
@Nullable
private static GithubUser retrieveCurrentUserInfo(@NotNull String url, @NotNull String login, @NotNull String password) {
try {
JsonElement result = getRequest(url, login, password, "/user");
JsonElement result = GithubApiUtil.getRequest(url, login, password, "/user");
return parseUserInfo(result);
}
catch (IOException e) {
@@ -270,22 +135,12 @@ public class GithubUtil {
return GithubUser.Plan.fromString(plan.getAsJsonObject().get("name").getAsString());
}
@NotNull
private static JsonElement parseResponse(@NotNull String githubResponse) throws IOException {
try {
return new JsonParser().parse(githubResponse);
}
catch (JsonSyntaxException jse) {
throw new IOException(String.format("Couldn't parse GitHub response:%n%s", githubResponse), jse);
}
}
@NotNull
private static List<RepositoryInfo> getAvailableRepos(@NotNull String url, @NotNull String login, @NotNull String password,
boolean ownOnly) {
final String request = (ownOnly ? "/user/repos" : "/user/watched");
try {
JsonElement result = getRequest(url, login, password, request);
JsonElement result = GithubApiUtil.getRequest(url, login, password, request);
if (result == null) {
return Collections.emptyList();
}
@@ -328,7 +183,7 @@ public class GithubUtil {
@NotNull String owner, @NotNull String name) {
try {
final String request = "/repos/" + owner + "/" + name;
JsonElement jsonObject = getRequest(url, login, password, request);
JsonElement jsonObject = GithubApiUtil.getRequest(url, login, password, request);
if (jsonObject == null) {
LOG.info(String.format("Information about repository is unavailable. Owner: %s, Name: %s", owner, name));
return null;
+5 -2
View File
@@ -260,7 +260,7 @@
<readWriteAccessDetector implementation="org.jetbrains.plugins.groovy.findUsages.GroovyReadWriteAccessDetector" order="before java"/>
<findUsagesHandlerFactory implementation="org.jetbrains.plugins.groovy.findUsages.GroovyFindUsagesHandlerFactory"/>
<highlightUsagesHandlerFactory implementation="org.jetbrains.plugins.groovy.findUsages.GrHighlightOverridingMethodsHandlerFactory"/>
<highlightUsagesHandlerFactory implementation="org.jetbrains.plugins.groovy.findUsages.GrHighlightHandlerFactory"/>
<lang.braceMatcher language="Groovy" implementationClass="org.jetbrains.plugins.groovy.highlighter.GroovyBraceMatcher"/>
<lang.importOptimizer language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.editor.GroovyImportOptimizer"/>
<lang.documentationProvider language="Groovy"
@@ -1363,7 +1363,10 @@
<implementation-class>org.jetbrains.plugins.groovy.codeInspection.local.GroovyUnusedImportsPassFactory</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.plugins.groovy.annotator.KeywordHighlightFactory</implementation-class>
<implementation-class>org.jetbrains.plugins.groovy.annotator.GrKeywordAndDeclarationHighlightFactory</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.plugins.groovy.annotator.GrReferenceHighlighterFactory</implementation-class>
</component>
<component>
<interface-class>org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicManager</interface-class>
@@ -80,7 +80,7 @@ public class GroovyTemplatesFactory implements FileTemplateGroupDescriptorFactor
@NonNls String... parameters) throws IncorrectOperationException {
final FileTemplate template = FileTemplateManager.getInstance().getInternalTemplate(templateName);
Properties properties = new Properties(FileTemplateManager.getInstance().getDefaultProperties());
Properties properties = new Properties(FileTemplateManager.getInstance().getDefaultProperties(directory.getProject()));
JavaTemplateUtil.setPackageNameAttribute(properties, directory);
properties.setProperty(NAME_TEMPLATE_PROPERTY, name);
properties.setProperty(LOW_CASE_NAME_TEMPLATE_PROPERTY, name.substring(0, 1).toLowerCase() + name.substring(1));
@@ -0,0 +1,186 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.annotator;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.PomDeclarationSearcher;
import com.intellij.pom.PomTarget;
import com.intellij.psi.*;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.CollectConsumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.extensions.GroovyUnresolvedHighlightFilter;
import org.jetbrains.plugins.groovy.highlighter.DefaultHighlighter;
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrUnaryExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
/**
* @author Max Medvedev
*/
public class GrHighlightUtil {
private static final Logger LOG = Logger.getInstance(GrHighlightUtil.class);
static boolean isReassigned(GrVariable var) {
PsiMethod method = PsiTreeUtil.getParentOfType(var, PsiMethod.class);
PsiNamedElement scope = method == null ? var.getContainingFile() : method;
if (scope == null) {
return false;
}
boolean hasAssignment = var.getInitializerGroovy() != null || var instanceof GrParameter;
for (PsiReference reference : ReferencesSearch.search(var, new LocalSearchScope(scope)).findAll()) {
if (reference instanceof GrReferenceExpression &&
(PsiUtil.isLValue((GrReferenceExpression)reference) ||
((GrReferenceExpression)reference).getParent() instanceof GrUnaryExpression &&
((GrUnaryExpression)((GrReferenceExpression)reference).getParent()).isPostfix())) {
if (hasAssignment) {
return true;
}
hasAssignment = true;
}
}
return false;
}
@Nullable
static TextAttributesKey getDeclarationHighlightingAttribute(PsiElement resolved) {
if (resolved instanceof PsiField || resolved instanceof GrVariable && ResolveUtil.isScriptField((GrVariable)resolved)) {
boolean isStatic = ((PsiVariable)resolved).hasModifierProperty(PsiModifier.STATIC);
return isStatic ? DefaultHighlighter.STATIC_FIELD : DefaultHighlighter.INSTANCE_FIELD;
}
else if (resolved instanceof GrAccessorMethod) {
boolean isStatic = ((GrAccessorMethod)resolved).hasModifierProperty(PsiModifier.STATIC);
return isStatic ? DefaultHighlighter.STATIC_PROPERTY_REFERENCE : DefaultHighlighter.INSTANCE_PROPERTY_REFERENCE;
}
else if (resolved instanceof PsiMethod) {
if (!((PsiMethod)resolved).isConstructor()) {
boolean isStatic = ((PsiMethod)resolved).hasModifierProperty(PsiModifier.STATIC);
if (GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod)resolved)) {
return isStatic ? DefaultHighlighter.STATIC_PROPERTY_REFERENCE : DefaultHighlighter.INSTANCE_PROPERTY_REFERENCE;
}
else {
return isStatic ? DefaultHighlighter.STATIC_METHOD_ACCESS : DefaultHighlighter.METHOD_CALL;
}
}
}
else if (resolved instanceof PsiTypeParameter) {
return DefaultHighlighter.TYPE_PARAMETER;
}
else if (resolved instanceof PsiClass) {
if (((PsiClass)resolved).isAnnotationType()) {
return DefaultHighlighter.ANNOTATION;
}
else {
return DefaultHighlighter.CLASS_REFERENCE;
}
}
else if (resolved instanceof GrParameter) {
boolean reassigned = isReassigned((GrParameter)resolved);
return reassigned ? DefaultHighlighter.REASSIGNED_PARAMETER : DefaultHighlighter.PARAMETER;
}
else if (resolved instanceof GrVariable) {
boolean reassigned = isReassigned((GrVariable)resolved);
return reassigned ? DefaultHighlighter.REASSIGNED_LOCAL_VARIABLE : DefaultHighlighter.LOCAL_VARIABLE;
}
return null;
}
public static boolean isDeclarationAssignment(GrReferenceExpression refExpr) {
if (isAssignmentLhs(refExpr)) {
return isExpandoQualified(refExpr);
}
return false;
}
private static boolean isAssignmentLhs(GrReferenceExpression refExpr) {
return refExpr.getParent() instanceof GrAssignmentExpression &&
refExpr.equals(((GrAssignmentExpression)refExpr.getParent()).getLValue());
}
private static boolean isExpandoQualified(GrReferenceExpression refExpr) {
final GrExpression qualifier = refExpr.getQualifierExpression();
if (qualifier == null) {
final PsiClass clazz = PsiTreeUtil.getParentOfType(refExpr, PsiClass.class);
if (clazz == null) { //script
return true;
}
return false; //in class, a property should normally be defined, so it's not a declaration
}
final PsiType type = qualifier.getType();
if (type instanceof PsiClassType) {
final PsiClassType classType = (PsiClassType)type;
final PsiClass psiClass = classType.resolve();
if (psiClass instanceof GroovyScriptClass) {
return true;
}
}
return false;
}
public static boolean shouldHighlightAsUnresolved(@NotNull GrReferenceExpression referenceExpression) {
PsiElement refNameElement = referenceExpression.getReferenceNameElement();
if (refNameElement != null && referenceExpression.getQualifier() == null) {
final IElementType type = refNameElement.getNode().getElementType();
if (TokenSets.STRING_LITERAL_SET.contains(type)) return false;
}
if (!GroovyUnresolvedHighlightFilter.shouldHighlight(referenceExpression)) return false;
CollectConsumer<PomTarget> consumer = new CollectConsumer<PomTarget>();
for (PomDeclarationSearcher searcher : PomDeclarationSearcher.EP_NAME.getExtensions()) {
searcher.findDeclarationsAt(referenceExpression, 0, consumer);
if (consumer.getResult().size() > 0) return false;
}
return true;
}
public static TextRange getMethodHeaderTextRange(PsiMethod method) {
final PsiModifierList modifierList = method.getModifierList();
final PsiParameterList parameterList = method.getParameterList();
final TextRange textRange = modifierList.getTextRange();
LOG.assertTrue(textRange != null, method.getClass() + ":" + method.getText());
int startOffset = textRange.getStartOffset();
int endOffset = parameterList.getTextRange().getEndOffset() + 1;
return new TextRange(startOffset, endOffset);
}
@NotNull
public static PsiElement getElementToHighlight(@NotNull GrReferenceElement refElement) {
final PsiElement refNameElement = refElement.getReferenceNameElement();
return refNameElement != null ? refNameElement : refElement;
}
}
@@ -0,0 +1,44 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.annotator;
import com.intellij.codeHighlighting.TextEditorHighlightingPass;
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory;
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
/**
* @author Max Medvedev
*/
public class GrKeywordAndDeclarationHighlightFactory extends AbstractProjectComponent implements TextEditorHighlightingPassFactory {
protected GrKeywordAndDeclarationHighlightFactory(Project project) {
super(project);
TextEditorHighlightingPassRegistrar.getInstance(project).registerTextEditorHighlightingPass(this, null, null, false, -1);
}
@Override
public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull Editor editor) {
if (!(file instanceof GroovyFile)) return null;
return new GrKeywordAndDeclarationHighlighter((GroovyFile)file, editor.getDocument());
}
}
@@ -20,16 +20,20 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiRecursiveElementVisitor;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.highlighter.DefaultHighlighter;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
import org.jetbrains.plugins.groovy.lang.psi.GrNamedElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
@@ -40,12 +44,12 @@ import java.util.List;
/**
* @author Max Medvedev
*/
public class KeywordHighlighter extends TextEditorHighlightingPass {
public class GrKeywordAndDeclarationHighlighter extends TextEditorHighlightingPass {
private final GroovyFile myFile;
private List<HighlightInfo> toHighlight;
protected KeywordHighlighter(GroovyFile file, Document document) {
protected GrKeywordAndDeclarationHighlighter(GroovyFile file, Document document) {
super(file.getProject(), document);
myFile = file;
}
@@ -58,7 +62,15 @@ public class KeywordHighlighter extends TextEditorHighlightingPass {
public void visitElement(PsiElement element) {
IElementType tokenType = element.getNode().getElementType();
if (TokenSets.KEYWORDS.contains(tokenType)) {
highlightKeyword(element, result, tokenType);
if (highlightKeyword(element, tokenType)) {
result.add(HighlightInfo.createHighlightInfo(HighlightInfoType.INFORMATION, element, null, DefaultHighlighter.KEYWORD));
}
}
else if (!(element instanceof GroovyPsiElement)) {
final TextAttributesKey attribute = getDeclarationAttribute(element);
if (attribute != null) {
result.add(HighlightInfo.createHighlightInfo(HighlightInfoType.INFORMATION, element, null, attribute));
}
}
else {
super.visitElement(element);
@@ -68,20 +80,20 @@ public class KeywordHighlighter extends TextEditorHighlightingPass {
toHighlight = result;
}
private static void highlightKeyword(PsiElement element, List<HighlightInfo> result, IElementType token) {
private static boolean highlightKeyword(PsiElement element, IElementType token) {
final PsiElement parent = element.getParent();
if (parent instanceof GrArgumentLabel) return; //don't highlight: print (void:'foo')
if (parent instanceof GrArgumentLabel) return false; //don't highlight: print (void:'foo')
if (PsiTreeUtil.getParentOfType(element, GrCodeReferenceElement.class) != null) {
if (token == GroovyTokenTypes.kDEF || token == GroovyTokenTypes.kIN || token == GroovyTokenTypes.kAS) {
return; //It is allowed to name packages 'as', 'in' or 'def'
return false; //It is allowed to name packages 'as', 'in' or 'def'
}
}
else if (parent instanceof GrReferenceExpression && element == ((GrReferenceExpression)parent).getReferenceNameElement()) {
return; //don't highlight foo.def
return false; //don't highlight foo.def
}
result.add(HighlightInfo.createHighlightInfo(HighlightInfoType.INFORMATION, element, null, DefaultHighlighter.KEYWORD));
return true;
}
@@ -90,4 +102,14 @@ public class KeywordHighlighter extends TextEditorHighlightingPass {
if (toHighlight == null) return;
UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument, 0, myFile.getTextLength(), toHighlight, getColorsScheme(), getId());
}
@Nullable
private static TextAttributesKey getDeclarationAttribute(PsiElement element) {
PsiElement parent = element.getParent();
if (!(parent instanceof GrNamedElement) || ((GrNamedElement)parent).getNameIdentifierGroovy() != element) {
return null;
}
return GrHighlightUtil.getDeclarationHighlightingAttribute(parent);
}
}
@@ -0,0 +1,88 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.annotator;
import com.intellij.codeHighlighting.TextEditorHighlightingPass;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
import java.util.ArrayList;
import java.util.List;
/**
* @author Max Medvedev
*/
public class GrReferenceHighlighter extends TextEditorHighlightingPass {
@NotNull private final GroovyFile myFile;
@Nullable private List<HighlightInfo> myInfos = null;
protected GrReferenceHighlighter(@Nullable Document document, @NotNull GroovyFile file) {
super(file.getProject(), document);
myFile = file;
}
@Override
public void doCollectInformation(@NotNull ProgressIndicator progress) {
myInfos = new ArrayList<HighlightInfo>();
myFile.accept(new GroovyRecursiveElementVisitor() {
@Override
public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
super.visitReferenceExpression(referenceExpression);
visit(referenceExpression);
}
private void visit(GrReferenceElement element) {
final PsiElement resolved = element.resolve();
final TextAttributesKey attribute = GrHighlightUtil.getDeclarationHighlightingAttribute(resolved);
if (attribute != null) {
final PsiElement refNameElement = GrHighlightUtil.getElementToHighlight(element);
myInfos.add(HighlightInfo.createHighlightInfo(HighlightInfoType.INFORMATION, refNameElement, null, attribute));
}
}
@Override
public void visitCodeReferenceElement(GrCodeReferenceElement refElement) {
super.visitCodeReferenceElement(refElement);
visit(refElement);
}
@Override
public void visitAnnotation(GrAnnotation annotation) {
super.visitAnnotation(annotation);
visit(annotation.getClassReference());
}
});
}
@Override
public void doApplyInformationToEditor() {
if (myInfos == null) return;
UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument, 0, myFile.getTextLength(), myInfos, getColorsScheme(), getId());
}
}
@@ -28,17 +28,15 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
/**
* @author Max Medvedev
*/
public class KeywordHighlightFactory extends AbstractProjectComponent implements TextEditorHighlightingPassFactory {
protected KeywordHighlightFactory(Project project) {
public class GrReferenceHighlighterFactory extends AbstractProjectComponent implements TextEditorHighlightingPassFactory {
protected GrReferenceHighlighterFactory(Project project) {
super(project);
TextEditorHighlightingPassRegistrar.getInstance(project).registerTextEditorHighlightingPass(this, null, null, false, -1);
}
@Override
public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull Editor editor) {
if (!(file instanceof GroovyFile)) return null;
return new KeywordHighlighter((GroovyFile)file, editor.getDocument());
return new GrReferenceHighlighter(editor.getDocument(), (GroovyFile)file);
}
}
@@ -38,19 +38,14 @@ import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.PomDeclarationSearcher;
import com.intellij.pom.PomTarget;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightElement;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.search.searches.SuperMethodsSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.CollectConsumer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import com.intellij.util.containers.MultiMap;
@@ -64,7 +59,6 @@ import org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicProperty
import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection;
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
import org.jetbrains.plugins.groovy.debugger.fragments.GroovyCodeFragment;
import org.jetbrains.plugins.groovy.extensions.GroovyUnresolvedHighlightFilter;
import org.jetbrains.plugins.groovy.highlighter.DefaultHighlighter;
import org.jetbrains.plugins.groovy.lang.documentation.GroovyPresentationUtil;
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocReferenceElement;
@@ -95,7 +89,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
@@ -111,7 +104,6 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrScriptField;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.noncode.GrInheritConstructorContributor;
@@ -137,104 +129,8 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
}
myHolder = null;
}
else {
highlightDeclaration(element, holder);
}
}
private static void highlightDeclaration(PsiElement element, AnnotationHolder holder) {
PsiElement parent = element.getParent();
if (!(parent instanceof GrNamedElement) || ((GrNamedElement)parent).getNameIdentifierGroovy() != element) {
return;
}
if (parent instanceof GrTypeParameter) {
final Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(DefaultHighlighter.TYPE_PARAMETER);
}
else if (parent instanceof GrAnnotationTypeDefinition) {
final Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(DefaultHighlighter.ANNOTATION);
}
else if (parent instanceof PsiClass) {
final Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(DefaultHighlighter.CLASS_REFERENCE);
}
else if (parent instanceof PsiMethod) {
if (!((PsiMethod)parent).isConstructor()) {
final Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(DefaultHighlighter.METHOD_DECLARATION);
}
}
else if (parent instanceof PsiField || parent instanceof GrVariable && ResolveUtil.isScriptField((GrVariable)parent)) {
final boolean isStatic = ((PsiVariable)parent).hasModifierProperty(PsiModifier.STATIC);
final Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(isStatic ? DefaultHighlighter.STATIC_FIELD : DefaultHighlighter.INSTANCE_FIELD);
}
else if (parent instanceof GrParameter) {
boolean reassigned = isReassigned((GrParameter)parent);
final Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(reassigned ? DefaultHighlighter.REASSIGNED_PARAMETER : DefaultHighlighter.PARAMETER);
}
else if (parent instanceof GrVariable) {
boolean reassigned = isReassigned((GrVariable)parent);
final Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(reassigned ? DefaultHighlighter.REASSIGNED_LOCAL_VARIABLE : DefaultHighlighter.LOCAL_VARIABLE);
}
}
private static void highlightResolved(AnnotationHolder holder, GrReferenceElement refElement, PsiElement resolved) {
final PsiElement refNameElement = getElementToHighlight(refElement);
if (resolved instanceof PsiField || resolved instanceof GrVariable && ResolveUtil.isScriptField((GrVariable)resolved)) {
boolean isStatic = ((PsiVariable)resolved).hasModifierProperty(PsiModifier.STATIC);
Annotation annotation = holder.createInfoAnnotation(refNameElement, null);
annotation.setTextAttributes(isStatic ? DefaultHighlighter.STATIC_FIELD : DefaultHighlighter.INSTANCE_FIELD);
}
else if (resolved instanceof GrAccessorMethod) {
boolean isStatic = ((GrAccessorMethod)resolved).hasModifierProperty(PsiModifier.STATIC);
Annotation annotation = holder.createInfoAnnotation(refNameElement, null);
annotation.setTextAttributes(isStatic ? DefaultHighlighter.STATIC_PROPERTY_REFERENCE : DefaultHighlighter.INSTANCE_PROPERTY_REFERENCE);
}
else if (resolved instanceof PsiMethod) {
boolean isStatic = ((PsiMethod)resolved).hasModifierProperty(PsiModifier.STATIC);
if (GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod)resolved)) {
Annotation annotation = holder.createInfoAnnotation(refNameElement, null);
annotation.setTextAttributes(isStatic ? DefaultHighlighter.STATIC_PROPERTY_REFERENCE : DefaultHighlighter.INSTANCE_PROPERTY_REFERENCE);
}
else {
Annotation annotation = holder.createInfoAnnotation(refNameElement, null);
annotation.setTextAttributes(isStatic ? DefaultHighlighter.STATIC_METHOD_ACCESS : DefaultHighlighter.METHOD_CALL);
}
}
else if (resolved instanceof PsiTypeParameter) {
Annotation annotation = holder.createInfoAnnotation(refNameElement, null);
annotation.setTextAttributes(DefaultHighlighter.TYPE_PARAMETER);
}
else if (resolved instanceof PsiClass) {
if (((PsiClass)resolved).isAnnotationType()) {
Annotation annotation = holder.createInfoAnnotation(refNameElement, null);
annotation.setTextAttributes(DefaultHighlighter.ANNOTATION);
}
else {
Annotation annotation = holder.createInfoAnnotation(refNameElement, null);
annotation.setTextAttributes(DefaultHighlighter.CLASS_REFERENCE);
}
}
else if (resolved instanceof GrParameter) {
boolean reassigned = isReassigned((GrParameter)resolved);
Annotation annotation = holder.createInfoAnnotation(refNameElement, null);
annotation.setTextAttributes(reassigned ? DefaultHighlighter.REASSIGNED_PARAMETER : DefaultHighlighter.PARAMETER);
}
else if (resolved instanceof GrVariable) {
boolean reassigned = isReassigned((GrVariable)resolved);
Annotation annotation = holder.createInfoAnnotation(refNameElement, null);
annotation.setTextAttributes(reassigned ? DefaultHighlighter.REASSIGNED_LOCAL_VARIABLE : DefaultHighlighter.LOCAL_VARIABLE);
}
}
@Override
public void visitTypeArgumentList(GrTypeArgumentList typeArgumentList) {
PsiElement parent = typeArgumentList.getParent();
@@ -319,8 +215,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
return;
}
highlightResolved(myHolder, refElement, resolveResult.getElement());
checkSingleResolvedElement(myHolder, refElement, resolveResult, true);
if (resolveResult.getElement() == null) {
@@ -408,8 +302,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
final PsiElement parent = referenceExpression.getParent();
if (resolved != null) {
highlightResolved(myHolder, referenceExpression, resolved);
if (!resolveResult.isStaticsOK() && resolved instanceof PsiModifierListOwner) {
if (!((PsiModifierListOwner)resolved).hasModifierProperty(PsiModifier.STATIC)) {
Annotation annotation = myHolder.createInfoAnnotation(referenceExpression, GroovyBundle.message("cannot.reference.nonstatic", referenceExpression.getReferenceName()));
@@ -419,7 +311,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
}
else {
GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null && isDeclarationAssignment(referenceExpression)) return;
if (qualifier == null && GrHighlightUtil.isDeclarationAssignment(referenceExpression)) return;
if (qualifier != null && referenceExpression.getDotTokenType() == GroovyTokenTypes.mMEMBER_POINTER) {
if (results.length > 0) {
@@ -447,9 +339,9 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
resolved = results[0].getElement();
}
}
if (isDeclarationAssignment(referenceExpression) || resolved instanceof PsiPackage) return;
if (GrHighlightUtil.isDeclarationAssignment(referenceExpression) || resolved instanceof PsiPackage) return;
if (resolved == null && shouldHighlightAsUnresolved(referenceExpression)) {
if (resolved == null && GrHighlightUtil.shouldHighlightAsUnresolved(referenceExpression)) {
PsiElement refNameElement = referenceExpression.getReferenceNameElement();
PsiElement elt = refNameElement == null ? referenceExpression : refNameElement;
@@ -490,46 +382,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
return context instanceof PsiMethod && context.hasModifierProperty(PsiModifier.STATIC);
}
private static boolean isReassigned(GrVariable var) {
PsiMethod method = PsiTreeUtil.getParentOfType(var, PsiMethod.class);
PsiNamedElement scope = method == null ? var.getContainingFile() : method;
if (scope == null) {
return false;
}
boolean hasAssignment = var.getInitializerGroovy() != null || var instanceof GrParameter;
for (PsiReference reference : ReferencesSearch.search(var, new LocalSearchScope(scope)).findAll()) {
if (reference instanceof GrReferenceExpression &&
(PsiUtil.isLValue((GrReferenceExpression)reference) ||
((GrReferenceExpression)reference).getParent() instanceof GrUnaryExpression &&
((GrUnaryExpression)((GrReferenceExpression)reference).getParent()).isPostfix())) {
if (hasAssignment) {
return true;
}
hasAssignment = true;
}
}
return false;
}
public static boolean shouldHighlightAsUnresolved(@NotNull GrReferenceExpression referenceExpression) {
PsiElement refNameElement = referenceExpression.getReferenceNameElement();
if (refNameElement != null && referenceExpression.getQualifier() == null) {
final IElementType type = refNameElement.getNode().getElementType();
if (TokenSets.STRING_LITERAL_SET.contains(type)) return false;
}
if (!GroovyUnresolvedHighlightFilter.shouldHighlight(referenceExpression)) return false;
CollectConsumer<PomTarget> consumer = new CollectConsumer<PomTarget>();
for (PomDeclarationSearcher searcher : PomDeclarationSearcher.EP_NAME.getExtensions()) {
searcher.findDeclarationsAt(referenceExpression, 0, consumer);
if (consumer.getResult().size() > 0) return false;
}
return true;
}
private void checkStringNameIdentifier(GrReferenceExpression ref) {
final PsiElement nameElement = ref.getReferenceNameElement();
if (nameElement == null) return;
@@ -543,41 +395,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
}
}
/*
private static void registerAccessFix(Annotation annotation, PsiElement place, PsiMember refElement) {
if (refElement instanceof PsiCompiledElement) return;
PsiModifierList modifierList = refElement.getModifierList();
if (modifierList == null) return;
try {
Project project = refElement.getProject();
JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
PsiModifierList modifierListCopy = facade.getElementFactory().createFieldFromText("int a;", null).getModifierList();
modifierListCopy.setModifierProperty(PsiModifier.STATIC, modifierList.hasModifierProperty(PsiModifier.STATIC));
@Modifier String minModifier = PsiModifier.PROTECTED;
if (refElement.hasModifierProperty(PsiModifier.PROTECTED)) {
minModifier = PsiModifier.PUBLIC;
}
String[] modifiers = {PsiModifier.PROTECTED, PsiModifier.PUBLIC, PsiModifier.PACKAGE_LOCAL};
PsiClass accessObjectClass = PsiTreeUtil.getParentOfType(place, PsiClass.class, false);
if (accessObjectClass == null) {
accessObjectClass = ((GroovyFile)place.getContainingFile()).getScriptClass();
}
for (int i = ArrayUtil.indexOf(modifiers, minModifier); i < modifiers.length; i++) {
String modifier = modifiers[i];
modifierListCopy.setModifierProperty(modifier, true);
if (facade.getResolveHelper().isAccessible(refElement, modifierListCopy, place, accessObjectClass, null)) {
IntentionAction fix = new GrModifierFix(refElement, refElement.getModifierList(), modifier, true, true);
annotation.registerFix(fix);
}
}
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
*/
private static void registerStaticImportFix(GrReferenceExpression referenceExpression, Annotation annotation) {
final String referenceName = referenceExpression.getReferenceName();
//noinspection ConstantConditions
@@ -650,7 +467,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
}
if (!hasImplicitDefConstructor && (defConstructor == null || !PsiUtil.isAccessible(typeDefinition, defConstructor))) {
holder.createErrorAnnotation(getMethodHeaderTextRange(method),
holder.createErrorAnnotation(GrHighlightUtil.getMethodHeaderTextRange(method),
GroovyBundle.message("there.is.no.default.constructor.available.in.class.0", qName));
}
}
@@ -710,7 +527,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
if (constructor != null) {
PsiMethod circleStart = constructor;
do {
holder.createErrorAnnotation(getMethodHeaderTextRange(constructor),
holder.createErrorAnnotation(GrHighlightUtil.getMethodHeaderTextRange(constructor),
GroovyBundle.message("recursive.constructor.invocation"));
constructor = nodes.get(constructor);
}
@@ -719,18 +536,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
}
}
public static TextRange getMethodHeaderTextRange(PsiMethod method) {
final PsiModifierList modifierList = method.getModifierList();
final PsiParameterList parameterList = method.getParameterList();
final TextRange textRange = modifierList.getTextRange();
LOG.assertTrue(textRange != null, method.getClass() + ":" + method.getText());
int startOffset = textRange.getStartOffset();
int endOffset = parameterList.getTextRange().getEndOffset() + 1;
return new TextRange(startOffset, endOffset);
}
@Override
public void visitMethod(GrMethod method) {
@@ -1316,8 +1121,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
if (resolved == null) return;
assert resolved instanceof PsiClass;
highlightResolved(myHolder, ref, resolved);
PsiClass anno = (PsiClass) resolved;
if (!anno.isAnnotationType()) {
myHolder.createErrorAnnotation(ref, GroovyBundle.message("class.is.not.annotation", ((PsiClass)resolved).getQualifiedName()));
@@ -1692,7 +1495,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
String signaturePresentation = GroovyPresentationUtil.getSignaturePresentation(signature);
for (PsiMethod method : methods) {
//noinspection ConstantConditions
holder.createErrorAnnotation(getMethodHeaderTextRange(method), GroovyBundle
holder.createErrorAnnotation(GrHighlightUtil.getMethodHeaderTextRange(method), GroovyBundle
.message("method.duplicate", signaturePresentation, method.getContainingClass().getName()));
}
}
@@ -1901,46 +1704,12 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
}
}
public static boolean isDeclarationAssignment(GrReferenceExpression refExpr) {
if (isAssignmentLhs(refExpr)) {
return isExpandoQualified(refExpr);
}
return false;
}
private static boolean isAssignmentLhs(GrReferenceExpression refExpr) {
return refExpr.getParent() instanceof GrAssignmentExpression &&
refExpr.equals(((GrAssignmentExpression)refExpr.getParent()).getLValue());
}
private static boolean isExpandoQualified(GrReferenceExpression refExpr) {
final GrExpression qualifier = refExpr.getQualifierExpression();
if (qualifier == null) {
final PsiClass clazz = PsiTreeUtil.getParentOfType(refExpr, PsiClass.class);
if (clazz == null) { //script
return true;
}
return false; //in class, a property should normally be defined, so it's not a declaration
}
final PsiType type = qualifier.getType();
if (type instanceof PsiClassType) {
final PsiClassType classType = (PsiClassType)type;
final PsiClass psiClass = classType.resolve();
if (psiClass instanceof GroovyScriptClass) {
return true;
}
}
return false;
}
private static void checkSingleResolvedElement(AnnotationHolder holder,
GrReferenceElement refElement,
GroovyResolveResult resolveResult,
boolean highlightError) {
final PsiElement resolved = resolveResult.getElement();
final PsiElement toHighlight = getElementToHighlight(refElement);
final PsiElement toHighlight = GrHighlightUtil.getElementToHighlight(refElement);
if (resolved == null) {
String message = GroovyBundle.message("cannot.resolve", refElement.getReferenceName());
@@ -1968,13 +1737,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
}
}
@NotNull
public static PsiElement getElementToHighlight(@NotNull GrReferenceElement refElement) {
final PsiElement refNameElement = refElement.getReferenceNameElement();
return refNameElement != null ? refNameElement : refElement;
}
private static void registerAddImportFixes(GrReferenceElement refElement, Annotation annotation) {
final String referenceName = refElement.getReferenceName();
//noinspection ConstantConditions
@@ -35,7 +35,7 @@ import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.GroovyBundle;
import org.jetbrains.plugins.groovy.annotator.GroovyAnnotator;
import org.jetbrains.plugins.groovy.annotator.GrHighlightUtil;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle;
@@ -448,7 +448,7 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
PsiElement resolved = resolveResult.getElement();
if (resolved == null) {
GrExpression qualifier = referenceExpression.getQualifierExpression();
if (qualifier == null && GroovyAnnotator.isDeclarationAssignment(referenceExpression)) return;
if (qualifier == null && GrHighlightUtil.isDeclarationAssignment(referenceExpression)) return;
}
if (!checkCannotInferArgumentTypes(referenceExpression)) return;
@@ -20,7 +20,7 @@ import com.intellij.psi.*;
import com.intellij.util.containers.CollectionFactory;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.annotator.GroovyAnnotator;
import org.jetbrains.plugins.groovy.annotator.GrHighlightUtil;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.gpp.GppTypeConverter;
@@ -34,7 +34,7 @@ import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import java.util.Iterator;
import java.util.List;
import static org.jetbrains.plugins.groovy.annotator.GroovyAnnotator.isDeclarationAssignment;
import static org.jetbrains.plugins.groovy.annotator.GrHighlightUtil.isDeclarationAssignment;
/**
* @author Maxim.Medvedev
@@ -76,7 +76,7 @@ public class GroovyUnresolvedAccessInspection extends BaseInspection {
PsiElement parent = refExpr.getParent();
if (!(parent instanceof GrCall) && ResolveUtil.isKeyOfMap(refExpr)) return; // It's a key of map.
if (!GroovyAnnotator.shouldHighlightAsUnresolved(refExpr)) return;
if (!GrHighlightUtil.shouldHighlightAsUnresolved(refExpr)) return;
if (qualifier != null && isBuilderInvocation(refExpr)) return;
@@ -28,7 +28,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import static org.jetbrains.plugins.groovy.annotator.GroovyAnnotator.isDeclarationAssignment;
import static org.jetbrains.plugins.groovy.annotator.GrHighlightUtil.isDeclarationAssignment;
/**
* @author Maxim.Medvedev
@@ -0,0 +1,77 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.findUsages;
import com.intellij.codeInsight.highlighting.HighlightUsagesHandlerBase;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.featureStatistics.ProductivityFeatureNames;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrThrowStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
import java.util.Collections;
import java.util.List;
/**
* @author Max Medvedev
*/
public class GrHighlightExitPointHandler extends HighlightUsagesHandlerBase<PsiElement> {
private final PsiElement myTarget;
protected GrHighlightExitPointHandler(Editor editor, PsiFile file, PsiElement target) {
super(editor, file);
myTarget = target;
}
@Override
public List<PsiElement> getTargets() {
return Collections.singletonList(myTarget);
}
@Override
protected void selectTargets(List<PsiElement> targets, Consumer<List<PsiElement>> selectionConsumer) {
selectionConsumer.consume(targets);
}
@Override
public void computeUsages(List<PsiElement> targets) {
FeatureUsageTracker.getInstance().triggerFeatureUsed(ProductivityFeatureNames.CODEASSISTS_HIGHLIGHT_RETURN);
PsiElement parent = myTarget.getParent();
if (!(parent instanceof GrReturnStatement) && !(parent instanceof GrThrowStatement)) return;
final GrControlFlowOwner flowOwner = ControlFlowUtils.findControlFlowOwner(parent);
ControlFlowUtils.visitAllExitPoints(flowOwner, new ControlFlowUtils.ExitPointVisitor() {
@Override
public boolean visitExitPoint(Instruction instruction, @Nullable GrExpression returnValue) {
final PsiElement returnElement = instruction.getElement();
if (returnElement == null) return true;
final TextRange range = returnElement.getTextRange();
myReadUsages.add(range);
return true;
}
});
}
}
@@ -30,7 +30,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini
/**
* @author Max Medvedev
*/
public class GrHighlightOverridingMethodsHandlerFactory implements HighlightUsagesHandlerFactory {
public class GrHighlightHandlerFactory implements HighlightUsagesHandlerFactory {
@Override
public HighlightUsagesHandlerBase createHighlightUsagesHandler(Editor editor, PsiFile file) {
int offset = TargetElementUtilBase.adjustOffset(editor.getDocument(), editor.getCaretModel().getOffset());
@@ -48,6 +48,9 @@ public class GrHighlightOverridingMethodsHandlerFactory implements HighlightUsag
if (!(grand instanceof GrTypeDefinition)) return null;
return new GrHighlightOverridingMethodsHandler(editor, file, target, (GrTypeDefinition)grand);
}
else if (type == GroovyTokenTypes.kRETURN || type == GroovyTokenTypes.kTHROW) {
return new GrHighlightExitPointHandler(editor, file, target);
}
return null;
}
}
@@ -26,7 +26,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.annotator.GroovyAnnotator;
import org.jetbrains.plugins.groovy.annotator.GrHighlightUtil;
import org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
@@ -82,7 +82,7 @@ public class AddReturnTypeFix implements IntentionAction {
}
final GrMethod method = PsiTreeUtil.getParentOfType(at, GrMethod.class, false, GrTypeDefinition.class, GrClosableBlock.class);
if (method != null && GroovyAnnotator.getMethodHeaderTextRange(method).contains(offset)) {
if (method != null && GrHighlightUtil.getMethodHeaderTextRange(method).contains(offset)) {
if (method.getReturnTypeElementGroovy() == null) {
return method;
}

Some files were not shown because too many files have changed in this diff Show More