diff --git a/.idea/externalDependencies.xml b/.idea/externalDependencies.xml index 3175a1f72809..8731c3e90e39 100644 --- a/.idea/externalDependencies.xml +++ b/.idea/externalDependencies.xml @@ -9,6 +9,6 @@ - + \ No newline at end of file diff --git a/build/download_kotlin.xml b/build/download_kotlin.xml index 4b1360bbadcc..937b11d21088 100644 --- a/build/download_kotlin.xml +++ b/build/download_kotlin.xml @@ -1,5 +1,5 @@ - + diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java index d7968fa6b95d..7f39de64c579 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -63,6 +63,7 @@ import static com.intellij.codeInsight.completion.ReferenceExpressionCompletionC import static com.intellij.patterns.PlatformPatterns.psiElement; public class JavaCompletionUtil { + public static final Key FORCE_SHOW_SIGNATURE_ATTR = Key.create("forceShowSignature"); private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.JavaCompletionUtil"); public static final Key> DYNAMIC_TYPE_EVALUATOR = Key.create("DYNAMIC_TYPE_EVALUATOR"); @@ -102,7 +103,7 @@ public class JavaCompletionUtil { private static final Key>> ALL_METHODS_ATTRIBUTE = Key.create("allMethods"); - public static PsiType getQualifierType(LookupItem item) { + public static PsiType getQualifierType(LookupElement item) { return item.getUserData(QUALIFIER_TYPE_ATTR); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java index 9698aa389779..5c8e7056d372 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java @@ -22,8 +22,9 @@ import com.intellij.codeInsight.editorActions.wordSelection.DocTagSelectioner; import com.intellij.codeInsight.javadoc.JavaDocUtil; import com.intellij.codeInsight.lookup.*; import com.intellij.codeInspection.InspectionProfile; -import com.intellij.codeInspection.SuppressionUtil; +import com.intellij.codeInspection.SuppressionUtilCore; import com.intellij.codeInspection.javaDoc.JavaDocLocalInspection; +import com.intellij.codeInspection.javaDoc.JavaDocLocalInspectionBase; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.*; import com.intellij.openapi.project.Project; @@ -98,7 +99,7 @@ public class JavaDocCompletionContributor extends CompletionContributor { JavaConstantExpressionEvaluator.computeConstantExpression(field.getInitializer(), false) != null)) continue; } - item.putUserData(LookupItem.FORCE_SHOW_SIGNATURE_ATTR, Boolean.TRUE); + item.putUserData(JavaCompletionUtil.FORCE_SHOW_SIGNATURE_ATTR, Boolean.TRUE); if (isArg) { item = AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(item); } @@ -228,7 +229,7 @@ public class JavaDocCompletionContributor extends CompletionContributor { for (JavadocTagInfo info : JavadocManager.SERVICE.getInstance(position.getProject()).getTagInfos(parent)) { String tagName = info.getName(); - if (tagName.equals(SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME)) continue; + if (tagName.equals(SuppressionUtilCore.SUPPRESS_INSPECTIONS_TAG_NAME)) continue; if (isInline != info.isInline()) continue; ret.add(tagName); addSpecialTags(ret, comment, tagName); @@ -237,7 +238,7 @@ public class JavaDocCompletionContributor extends CompletionContributor { InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(position.getProject()).getInspectionProfile(); JavaDocLocalInspection inspection = - (JavaDocLocalInspection)inspectionProfile.getUnwrappedTool(JavaDocLocalInspection.SHORT_NAME, position); + (JavaDocLocalInspection)inspectionProfile.getUnwrappedTool(JavaDocLocalInspectionBase.SHORT_NAME, position); if (inspection != null) { final StringTokenizer tokenizer = new StringTokenizer(inspection.myAdditionalJavadocTags, ", "); while (tokenizer.hasMoreTokens()) { @@ -265,7 +266,7 @@ public class JavaDocCompletionContributor extends CompletionContributor { if (psiMethod != null) { PsiDocTag[] tags = comment.getTags(); for (PsiParameter param : psiMethod.getParameterList().getParameters()) { - if (!JavaDocLocalInspection.isFound(tags, param)) { + if (!JavaDocLocalInspectionBase.isFound(tags, param)) { result.add(tagName + " " + param.getName()); } } @@ -302,6 +303,7 @@ public class JavaDocCompletionContributor extends CompletionContributor { final int offset = caretModel.getOffset(); final PsiElement element = context.getFile().findElementAt(offset - 1); PsiDocTag tag = PsiTreeUtil.getParentOfType(element, PsiDocTag.class); + assert tag != null; for (PsiElement child = tag.getFirstChild(); child != null; child = child.getNextSibling()) { if (child instanceof PsiDocToken) { @@ -334,18 +336,15 @@ public class JavaDocCompletionContributor extends CompletionContributor { } } - private static class MethodSignatureInsertHandler implements InsertHandler { + private static class MethodSignatureInsertHandler implements InsertHandler { @Override - public void handleInsert(InsertionContext context, LookupItem item) { - if (!(item.getObject() instanceof PsiMethod)) { - return; - } + public void handleInsert(InsertionContext context, JavaMethodCallElement item) { PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getEditor().getDocument()); final Editor editor = context.getEditor(); - final PsiMethod method = (PsiMethod)item.getObject(); + final PsiMethod method = item.getObject(); final PsiParameter[] parameters = method.getParameterList().getParameters(); - final StringBuffer buffer = new StringBuffer(); + final StringBuilder buffer = new StringBuilder(); final CharSequence chars = editor.getDocument().getCharsSequence(); int endOffset = editor.getCaretModel().getOffset(); @@ -354,18 +353,20 @@ public class JavaDocCompletionContributor extends CompletionContributor { int signatureOffset = afterSharp; PsiElement element = context.getFile().findElementAt(signatureOffset - 1); - final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(element.getProject()); + final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(context.getProject()); PsiDocTag tag = PsiTreeUtil.getParentOfType(element, PsiDocTag.class); - if (context.getCompletionChar() == Lookup.REPLACE_SELECT_CHAR) { + if (context.getCompletionChar() == Lookup.REPLACE_SELECT_CHAR && tag != null) { final PsiDocTagValue valueElement = tag.getValueElement(); - endOffset = valueElement.getTextRange().getEndOffset(); - context.setTailOffset(endOffset); + if (valueElement != null) { + endOffset = valueElement.getTextRange().getEndOffset(); + context.setTailOffset(endOffset); + } } editor.getDocument().deleteString(afterSharp, endOffset); editor.getCaretModel().moveToOffset(signatureOffset); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); editor.getSelectionModel().removeSelection(); - buffer.append(method.getName() + "("); + buffer.append(method.getName()).append("("); final int afterParenth = afterSharp + buffer.length(); for (int i = 0; i < parameters.length; i++) { final PsiType type = TypeConversionUtil.erasure(parameters[i].getType()); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodCallElement.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodCallElement.java index cf74e132c3fd..9ca6c2680015 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodCallElement.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodCallElement.java @@ -128,7 +128,7 @@ public class JavaMethodCallElement extends LookupItem implements Type final PsiMethod method = getObject(); final LookupElement[] allItems = context.getElements(); - final boolean overloadsMatter = allItems.length == 1 && getUserData(FORCE_SHOW_SIGNATURE_ATTR) == null; + final boolean overloadsMatter = allItems.length == 1 && getUserData(JavaCompletionUtil.FORCE_SHOW_SIGNATURE_ATTR) == null; final boolean hasParams = MethodParenthesesHandler.hasParams(this, allItems, overloadsMatter, method); JavaCompletionUtil.insertParentheses(context, this, overloadsMatter, hasParams); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java index 29fd7ee5c09f..c9e8ae1f78db 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java @@ -16,7 +16,6 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; @@ -44,7 +43,7 @@ public class JavaMethodMergingContributor extends CompletionContributor { final ArrayList allMethods = new ArrayList(); for (LookupElement item : items) { Object o = item.getPsiElement(); - if (item.getUserData(LookupItem.FORCE_SHOW_SIGNATURE_ATTR) != null || !(o instanceof PsiMethod)) { + if (item.getUserData(JavaCompletionUtil.FORCE_SHOW_SIGNATURE_ATTR) != null || !(o instanceof PsiMethod)) { return AutoCompletionDecision.SHOW_LOOKUP; } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java index e04e5ed35df3..2713ca52a1ea 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java @@ -155,12 +155,10 @@ public class JavaPsiClassReferenceElement extends LookupItem implements @Override public void renderElement(LookupElementPresentation presentation) { - LookupItem item = this; - PsiClass psiClass = getObject(); - renderClassItem(presentation, item, psiClass, false, " (" + myPackageDisplayName + ")", mySubstitutor); + renderClassItem(presentation, this, getObject(), false, " (" + myPackageDisplayName + ")", mySubstitutor); } - public static void renderClassItem(LookupElementPresentation presentation, LookupItem item, PsiClass psiClass, boolean diamond, + public static void renderClassItem(LookupElementPresentation presentation, LookupElement item, PsiClass psiClass, boolean diamond, @NotNull String locationString, @NotNull PsiSubstitutor substitutor) { if (!(psiClass instanceof PsiTypeParameter)) { presentation.setIcon(DefaultLookupItemRenderer.getRawIcon(item, presentation.isReal())); @@ -194,7 +192,7 @@ public class JavaPsiClassReferenceElement extends LookupItem implements return " (" + myPackageDisplayName + ")"; } - private static String getName(final PsiClass psiClass, final LookupItem item, boolean diamond, @NotNull PsiSubstitutor substitutor) { + private static String getName(final PsiClass psiClass, final LookupElement item, boolean diamond, @NotNull PsiSubstitutor substitutor) { if (item instanceof JavaPsiClassReferenceElement) { String forced = ((JavaPsiClassReferenceElement)item).getForcedPresentableName(); if (forced != null) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index 11384bdeeb05..6a6d14d08d4c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -342,7 +342,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor { } @NotNull - private TailTypeDecorator createCatchTypeVariant(PsiCodeBlock tryBlock, PsiClassType type) { + private LookupElement createCatchTypeVariant(PsiCodeBlock tryBlock, PsiClassType type) { return TailTypeDecorator.withTail(PsiTypeLookupItem.createLookupItem(type, tryBlock).setInsertHandler(new DefaultInsertHandler()), TailType.HUMBLE_SPACE_BEFORE_WORD); } diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/LookupItemUtil.java b/java/java-impl/src/com/intellij/codeInsight/lookup/LookupItemUtil.java index aaa1bb896a3c..97714e962350 100644 --- a/java/java-impl/src/com/intellij/codeInsight/lookup/LookupItemUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/lookup/LookupItemUtil.java @@ -18,8 +18,6 @@ package com.intellij.codeInsight.lookup; import com.intellij.codeInsight.TailType; import com.intellij.codeInsight.completion.JavaClassNameCompletionContributor; import com.intellij.codeInsight.completion.JavaMethodCallElement; -import com.intellij.codeInsight.completion.PrefixMatcher; -import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; import com.intellij.codeInsight.template.Template; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; @@ -40,13 +38,11 @@ import java.util.Collection; public class LookupItemUtil{ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.lookup.LookupItemUtil"); + /** + * @deprecated to remove in IDEA 16 + */ @Nullable public static LookupElement addLookupItem(Collection set, @NotNull Object object) { - return addLookupItem(set, object, new CamelHumpMatcher("")); - } - - @Nullable - public static LookupElement addLookupItem(Collection set, @NotNull Object object, PrefixMatcher matcher) { if (object instanceof PsiType) { PsiType psiType = (PsiType)object; for (final LookupElement lookupItem : set) { @@ -61,10 +57,7 @@ public class LookupItemUtil{ if(lookupItem.getObject().equals(lookupItem)) return null; } LookupElement item = objectToLookupItem(object); - if (matcher.prefixMatches(item)) { - return set.add(item) ? item : null; - } - return null; + return set.add(item) ? item : null; } /** diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/impl/JavaElementLookupRenderer.java b/java/java-impl/src/com/intellij/codeInsight/lookup/impl/JavaElementLookupRenderer.java index 3aaa20ae8239..ee8ba571a9c7 100644 --- a/java/java-impl/src/com/intellij/codeInsight/lookup/impl/JavaElementLookupRenderer.java +++ b/java/java-impl/src/com/intellij/codeInsight/lookup/impl/JavaElementLookupRenderer.java @@ -17,9 +17,13 @@ package com.intellij.codeInsight.lookup.impl; import com.intellij.codeInsight.completion.JavaCompletionUtil; import com.intellij.codeInsight.lookup.DefaultLookupItemRenderer; +import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementPresentation; import com.intellij.codeInsight.lookup.LookupItem; -import com.intellij.psi.*; +import com.intellij.psi.PsiDocCommentOwner; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiType; import com.intellij.psi.impl.beanProperties.BeanPropertyElement; import com.intellij.psi.util.PsiUtilCore; import org.jetbrains.annotations.Nullable; @@ -44,19 +48,11 @@ public class JavaElementLookupRenderer implements ElementLookupRenderer { presentation.setTailText((String)item.getAttribute(LookupItem.TAIL_TEXT_ATTR), item.getAttribute(LookupItem.TAIL_TEXT_SMALL_ATTR) != null); - presentation.setTypeText(getTypeText(item, ((BeanPropertyElement)element).getPropertyType())); + PsiType type = ((BeanPropertyElement)element).getPropertyType(); + presentation.setTypeText(type == null ? null : type.getPresentableText()); } - @Nullable - private static String getTypeText(LookupItem item, @Nullable PsiType returnType) { - if (returnType == null) { - return null; - } - - return returnType.getPresentableText(); - } - - public static boolean isToStrikeout(LookupItem item) { + public static boolean isToStrikeout(LookupElement item) { final List allMethods = JavaCompletionUtil.getAllMethods(item); if (allMethods != null){ for (PsiMethod method : allMethods) { @@ -69,16 +65,10 @@ public class JavaElementLookupRenderer implements ElementLookupRenderer { } return true; } - else if (item.getObject() instanceof PsiElement) { - final PsiElement element = (PsiElement)item.getObject(); - if (element.isValid()) { - return isDeprecated(element); - } - } - return false; + return isDeprecated(item.getPsiElement()); } - private static boolean isDeprecated(PsiElement element) { + private static boolean isDeprecated(@Nullable PsiElement element) { return element instanceof PsiDocCommentOwner && ((PsiDocCommentOwner)element).isDeprecated(); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/impl/JavaTemplateUtil.java b/java/java-impl/src/com/intellij/codeInsight/template/impl/JavaTemplateUtil.java index b93b364a6366..5600ce4623af 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/impl/JavaTemplateUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/impl/JavaTemplateUtil.java @@ -16,7 +16,6 @@ package com.intellij.codeInsight.template.impl; import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.codeInsight.lookup.LookupItemUtil; import com.intellij.codeInsight.lookup.PsiTypeLookupItem; import com.intellij.codeInsight.template.TemplateLookupSelectionHandler; @@ -156,19 +155,16 @@ public class JavaTemplateUtil { } public static LookupElement addElementLookupItem(Set items, PsiElement element) { - final LookupElement item = LookupItemUtil.addLookupItem(items, element); - if (item instanceof LookupItem) { - ((LookupItem)item).setAttribute(TemplateLookupSelectionHandler.KEY_IN_LOOKUP_ITEM, new JavaTemplateLookupSelectionHandler()); - } + final LookupElement item = LookupItemUtil.objectToLookupItem(element); + items.add(item); + item.putUserData(TemplateLookupSelectionHandler.KEY_IN_LOOKUP_ITEM, new JavaTemplateLookupSelectionHandler()); return item; } public static LookupElement addTypeLookupItem(Set items, PsiType type) { final LookupElement item = PsiTypeLookupItem.createLookupItem(type, null); items.add(item); - if (item instanceof LookupItem) { - ((LookupItem)item).setAttribute(TemplateLookupSelectionHandler.KEY_IN_LOOKUP_ITEM, new JavaTemplateLookupSelectionHandler()); - } + item.putUserData(TemplateLookupSelectionHandler.KEY_IN_LOOKUP_ITEM, new JavaTemplateLookupSelectionHandler()); return item; } } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java b/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java index 22029d8a3ad5..26ab784bd3b0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java @@ -17,7 +17,7 @@ package com.intellij.codeInsight.template.macro; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.template.*; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; @@ -65,10 +65,9 @@ public class SuggestVariableNameMacro extends Macro { public LookupElement[] calculateLookupItems(@NotNull Expression[] params, final ExpressionContext context) { String[] names = getNames(context); if (names == null || names.length < 2) return null; - LookupItem[] items = new LookupItem[names.length]; + LookupElement[] items = new LookupElement[names.length]; for(int i = 0; i < names.length; i++) { - String name = names[i]; - items[i] = LookupItem.fromString(name); + items[i] = LookupElementBuilder.create(names[i]); } return items; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java index 052d06997679..589eb35b2464 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupItem.java @@ -48,7 +48,6 @@ public class LookupItem extends MutableLookupElement implements Comparable public static final Object TYPE_TEXT_ATTR = Key.create("typeText"); public static final Object TAIL_TEXT_ATTR = Key.create("tailText"); public static final Object TAIL_TEXT_SMALL_ATTR = Key.create("tailTextSmall"); - public static final Key FORCE_SHOW_SIGNATURE_ATTR = Key.create("forceShowSignature"); public static final Object FORCE_QUALIFY = Key.create("FORCE_QUALIFY"); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateExpressionLookupElement.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateExpressionLookupElement.java index dd53e5aab241..11bb58a53f43 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateExpressionLookupElement.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateExpressionLookupElement.java @@ -22,7 +22,6 @@ import com.intellij.codeInsight.completion.OffsetMap; import com.intellij.codeInsight.completion.PrioritizedLookupElement; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementDecorator; -import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.codeInsight.template.TemplateLookupSelectionHandler; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; @@ -81,8 +80,7 @@ class TemplateExpressionLookupElement extends LookupElementDecorator)item).getAttribute(TemplateLookupSelectionHandler.KEY_IN_LOOKUP_ITEM) : null; + final TemplateLookupSelectionHandler handler = item.getUserData(TemplateLookupSelectionHandler.KEY_IN_LOOKUP_ITEM); if (handler != null && range != null) { handler.itemSelected(item, context.getFile(), context.getDocument(), range.getStartOffset(), range.getEndOffset()); } diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java index 524887345a86..c54bddeb35f7 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java @@ -377,7 +377,7 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent public Dimension getPreferredSize() { final boolean isEmpty = getIcon() == null && StringUtil.isEmpty(getText()); int width = isEmpty ? JBUI.scale(10) + ARROW_ICON.getIconWidth() : super.getPreferredSize().width; - if (isSmallVariant()) width += JBUI.scale(4); + if (isSmallVariant() && !(SystemInfo.isMac && UIUtil.isUnderIntelliJLaF())) width += JBUI.scale(4); return new Dimension(width, isSmallVariant() ? JBUI.scale(19) : super.getPreferredSize().height); } @@ -393,75 +393,88 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent @Override public void paint(Graphics g) { - UISettings.setupAntialiasing(g); - final Dimension size = getSize(); final boolean isEmpty = getIcon() == null && StringUtil.isEmpty(getText()); + final Dimension size = getSize(); - final Color textColor = isEnabled() - ? UIManager.getColor("Panel.foreground") - : UIUtil.getInactiveTextColor(); - if (myForceTransparent) { - final Icon icon = getIcon(); - int x = 7; - if (icon != null) { - icon.paintIcon(this, g, x, (size.height - icon.getIconHeight()) / 2); - x += icon.getIconWidth() + 3; - } - if (!StringUtil.isEmpty(getText())) { - final Font font = getFont(); - g.setFont(font); - g.setColor(textColor); - g.drawString(getText(), x, (size.height + font.getSize()) / 2 - 1); - } + if (SystemInfo.isMac && UIUtil.isUnderIntelliJLaF()) { + putClientProperty("styleCombo", Boolean.TRUE); + super.paint(g); } else { + UISettings.setupAntialiasing(g); - if (isSmallVariant()) { - final Graphics2D g2 = (Graphics2D)g; - g2.setColor(UIUtil.getControlColor()); - final int w = getWidth(); - final int h = getHeight(); - if (getModel().isArmed() && getModel().isPressed()) { - g2.setPaint(UIUtil.getGradientPaint(0, 0, UIUtil.getControlColor(), 0, h, ColorUtil.shift(UIUtil.getControlColor(), 0.8))); - } - else { - if (UIUtil.isUnderDarcula()) { - g2.setPaint(UIUtil.getGradientPaint(0, 0, ColorUtil.shift(UIUtil.getControlColor(), 1.1), 0, h, ColorUtil.shift(UIUtil.getControlColor(), 0.9))); - } else { - g2.setPaint(UIUtil.getGradientPaint(0, 0, new JBColor(SystemInfo.isMac? Gray._226 : Gray._245, Gray._131), 0, h, new JBColor(SystemInfo.isMac? Gray._198 : Gray._208, Gray._128))); + final Color textColor = isEnabled() + ? UIManager.getColor("Panel.foreground") + : UIUtil.getInactiveTextColor(); + if (myForceTransparent) { + final Icon icon = getIcon(); + int x = 7; + if (icon != null) { + icon.paintIcon(this, g, x, (size.height - icon.getIconHeight()) / 2); + x += icon.getIconWidth() + 3; + } + if (!StringUtil.isEmpty(getText())) { + final Font font = getFont(); + g.setFont(font); + g.setColor(textColor); + g.drawString(getText(), x, (size.height + font.getSize()) / 2 - 1); } } - g2.fillRoundRect(2, 0, w - 2, h, 5, 5); + else { - Color borderColor = myMouseInside ? new JBColor(Gray._111, Gray._118) : new JBColor(Gray._151, Gray._95); - g2.setPaint(borderColor); - g2.drawRoundRect(2, 0, w - 3, h - 1, 5, 5); + if (isSmallVariant()) { + final Graphics2D g2 = (Graphics2D)g; + g2.setColor(UIUtil.getControlColor()); + final int w = getWidth(); + final int h = getHeight(); + if (getModel().isArmed() && getModel().isPressed()) { + g2.setPaint(UIUtil.getGradientPaint(0, 0, UIUtil.getControlColor(), 0, h, ColorUtil.shift(UIUtil.getControlColor(), 0.8))); + } + else { + if (UIUtil.isUnderDarcula()) { + g2.setPaint(UIUtil.getGradientPaint(0, 0, ColorUtil.shift(UIUtil.getControlColor(), 1.1), 0, h, + ColorUtil.shift(UIUtil.getControlColor(), 0.9))); + } + else { + g2.setPaint(UIUtil.getGradientPaint(0, 0, new JBColor(SystemInfo.isMac ? Gray._226 : Gray._245, Gray._131), 0, h, + new JBColor(SystemInfo.isMac ? Gray._198 : Gray._208, Gray._128))); + } + } + g2.fillRoundRect(2, 0, w - 2, h, 5, 5); - final Icon icon = getIcon(); - int x = 7; - if (icon != null) { - icon.paintIcon(this, g, x, (size.height - icon.getIconHeight()) / 2); - x += icon.getIconWidth() + 3; - } - if (!StringUtil.isEmpty(getText())) { - final Font font = getFont(); - g2.setFont(font); - g2.setColor(textColor); - g2.drawString(getText(), x, (size.height + font.getSize()) / 2 - 1); + Color borderColor = myMouseInside ? new JBColor(Gray._111, Gray._118) : new JBColor(Gray._151, Gray._95); + g2.setPaint(borderColor); + g2.drawRoundRect(2, 0, w - 3, h - 1, 5, 5); + + final Icon icon = getIcon(); + int x = 7; + if (icon != null) { + icon.paintIcon(this, g, x, (size.height - icon.getIconHeight()) / 2); + x += icon.getIconWidth() + 3; + } + if (!StringUtil.isEmpty(getText())) { + final Font font = getFont(); + g2.setFont(font); + g2.setColor(textColor); + g2.drawString(getText(), x, (size.height + font.getSize()) / 2 - 1); + } + } + else { + super.paint(g); + } } } - else { - super.paint(g); - } - } final Insets insets = super.getInsets(); final Icon icon = isEnabled() ? ARROW_ICON : DISABLED_ARROW_ICON; - final int x; + int x; if (isEmpty) { x = (size.width - icon.getIconWidth()) / 2; } else { if (isSmallVariant()) { x = size.width - icon.getIconWidth() - insets.right + 1; + if (SystemInfo.isMac && UIUtil.isUnderIntelliJLaF()) { + x-=3; + } } else { x = size.width - icon.getIconWidth() - insets.right + (UIUtil.isUnderNimbusLookAndFeel() ? -3 : 2); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboLeft.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboLeft.png new file mode 100644 index 000000000000..16eb5e083f60 Binary files /dev/null and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboLeft.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboLeft@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboLeft@2x.png new file mode 100644 index 000000000000..937c8268b6d2 Binary files /dev/null and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboLeft@2x.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboMiddle.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboMiddle.png new file mode 100644 index 000000000000..0e759578621f Binary files /dev/null and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboMiddle.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboMiddle@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboMiddle@2x.png new file mode 100644 index 000000000000..7ff520f1f15a Binary files /dev/null and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboMiddle@2x.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboRight.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboRight.png new file mode 100644 index 000000000000..c945a5839a33 Binary files /dev/null and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboRight.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboRight@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboRight@2x.png new file mode 100644 index 000000000000..0b720a9e2384 Binary files /dev/null and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/buttonComboRight@2x.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboLeft.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboLeft.png new file mode 100644 index 000000000000..16eb5e083f60 Binary files /dev/null and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboLeft.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboLeft@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboLeft@2x.png new file mode 100644 index 000000000000..937c8268b6d2 Binary files /dev/null and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboLeft@2x.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboMiddle.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboMiddle.png new file mode 100644 index 000000000000..0e759578621f Binary files /dev/null and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboMiddle.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboMiddle@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboMiddle@2x.png new file mode 100644 index 000000000000..7ff520f1f15a Binary files /dev/null and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboMiddle@2x.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboRight.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboRight.png new file mode 100644 index 000000000000..c945a5839a33 Binary files /dev/null and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboRight.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboRight@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboRight@2x.png new file mode 100644 index 000000000000..0b720a9e2384 Binary files /dev/null and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/buttonComboRight@2x.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJButtonUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJButtonUI.java index f6551b60c04c..39f384c30933 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJButtonUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJButtonUI.java @@ -52,7 +52,6 @@ public class MacIntelliJButtonUI extends DarculaButtonUI { String text = layout(b, SwingUtilities2.getFontMetrics(b, g), b.getWidth(), b.getHeight()); - boolean isDefault = b instanceof JButton && ((JButton)b).isDefaultButton(); boolean isFocused = c.hasFocus(); if (isSquare(c)) { g.setColor(Gray.xFF); @@ -63,19 +62,19 @@ public class MacIntelliJButtonUI extends DarculaButtonUI { int x = isFocused ? 0 : 2; int y = isFocused ? 0 : (h - viewRect.height) / 2; Icon icon; - icon = MacIntelliJIconCache.getIcon("buttonLeft", isDefault, isFocused, false); + icon = getLeftIcon(b); icon.paintIcon(b, g, x, y); x += icon.getIconWidth(); - int stop = w - (isFocused ? 0 : 2) - (MacIntelliJIconCache.getIcon("buttonRight", isDefault, isFocused, false).getIconWidth()); + int stop = w - (isFocused ? 0 : 2) - (getRightIcon(b).getIconWidth()); Graphics gg = g.create(0, 0, w, h); gg.setClip(x, y, stop - x, h); - icon = MacIntelliJIconCache.getIcon("buttonMiddle", isDefault, isFocused, false); + icon = getMiddleIcon(b); while (x < stop) { icon.paintIcon(b, gg, x, y); x += icon.getIconWidth(); } gg.dispose(); - icon = MacIntelliJIconCache.getIcon("buttonRight", isDefault, isFocused, false); + icon = getRightIcon(b); icon.paintIcon(b, g, stop, y); clearTextShiftOffset(); @@ -97,6 +96,27 @@ public class MacIntelliJButtonUI extends DarculaButtonUI { } } + private static Icon getLeftIcon(AbstractButton button) { + return getIcon("Left", button); + } + + private static Icon getMiddleIcon(AbstractButton button) { + return getIcon("Middle", button); + } + + private static Icon getRightIcon(AbstractButton button) { + return getIcon("Right", button); + } + + private static Icon getIcon(String suffix, AbstractButton button) { + boolean isDefault = button instanceof JButton && ((JButton)button).isDefaultButton(); + boolean isFocused = button.hasFocus(); + boolean combo = button.getClientProperty("styleCombo") == Boolean.TRUE; + String comboPrefix = combo ? "Combo" : ""; + String iconName = "button" + comboPrefix + suffix; + return MacIntelliJIconCache.getIcon(iconName, isDefault, isFocused && !combo, false); + } + private String layout(AbstractButton b, FontMetrics fm, int width, int height) { Insets i = b.getInsets(); @@ -108,6 +128,10 @@ public class MacIntelliJButtonUI extends DarculaButtonUI { textRect.x = textRect.y = textRect.width = textRect.height = 0; iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0; + if (b.getClientProperty("styleCombo") == Boolean.TRUE) { + viewRect.x += 6; + } + // layout the text and icon return SwingUtilities.layoutCompoundLabel( b, fm, b.getText(), b.getIcon(), diff --git a/platform/platform-impl/src/com/intellij/remote/VagrantSupport.java b/platform/platform-impl/src/com/intellij/remote/VagrantSupport.java index 580509183d56..d941d4e154be 100644 --- a/platform/platform-impl/src/com/intellij/remote/VagrantSupport.java +++ b/platform/platform-impl/src/com/intellij/remote/VagrantSupport.java @@ -67,6 +67,9 @@ public abstract class VagrantSupport { return t.getMessage().contains("not yet ready for SSH"); } + @Nullable + public abstract String findVagrantFolder(@NotNull Project project); + public static class MultipleMachinesException extends Exception {} } diff --git a/platform/platform-resources/src/DefaultColorSchemesManager.xml b/platform/platform-resources/src/DefaultColorSchemesManager.xml index ac6de50f1edd..26f1e1d35d5b 100644 --- a/platform/platform-resources/src/DefaultColorSchemesManager.xml +++ b/platform/platform-resources/src/DefaultColorSchemesManager.xml @@ -6,7 +6,7 @@ diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerSettingsEditor.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerSettingsEditor.java index ec69360914bb..80dba20e58ae 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerSettingsEditor.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerSettingsEditor.java @@ -33,6 +33,7 @@ import com.intellij.remoteServer.configuration.deployment.DeploymentSourceType; import com.intellij.remoteServer.impl.configuration.RemoteServerListConfigurable; import com.intellij.ui.*; import com.intellij.util.ui.FormBuilder; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -202,7 +203,7 @@ public class DeployToServerSettingsEditor#ref is too short #loc -annotation.naming.convention.problem.descriptor.long=Annotation name #ref is too long #loc -annotation.naming.convention.problem.descriptor.regex.mismatch=Annotation name #ref doesn''t match regex ''{0}'' #loc -class.name.convention.problem.descriptor.short=Class name #ref is too short #loc -abstract.class.name.convention.problem.descriptor.short=Abstract class name #ref is too short #loc -class.name.convention.problem.descriptor.long=Class name #ref is too long #loc -abstract.class.name.convention.problem.descriptor.long=Abstract class name #ref is too long #loc -class.name.convention.problem.descriptor.regex.mismatch=Class name #ref doesn''t match regex ''{0}'' #loc -abstract.class.name.convention.problem.descriptor.regex.mismatch=Abstract class name #ref doesn''t match regex ''{0}'' #loc -constant.naming.convention.problem.descriptor.short=Constant name #ref is too short #loc -constant.naming.convention.problem.descriptor.long=Constant name #ref is too long #loc -constant.naming.convention.problem.descriptor.regex.mismatch=Constant #ref doesn''t match regex ''{0}'' #loc +naming.convention.problem.descriptor.short={0} name #ref is too short ({1} < {2}) #loc +naming.convention.problem.descriptor.long={0} name #ref is too long ({1} > {2}) #loc +naming.convention.problem.descriptor.regex.mismatch={0} name #ref doesn''t match regex ''{1}'' #loc constant.naming.convention.immutables.option=Only check 'static final' fields with immutable types -enumerated.class.naming.convention.problem.descriptor.short=Enumerated class name #ref is too short #loc -enumerated.class.naming.convention.problem.descriptor.long=Enumerated class name #ref is too long #loc -enumerated.class.naming.convention.problem.descriptor.regex.mismatch=Enumerated class name #ref doesn''t match regex ''{0}'' #loc -enumerated.constant.naming.convention.problem.descriptor.short=Enumerated constant name #ref is too short #loc -enumerated.constant.naming.convention.problem.descriptor.long=Enumerated constant name #ref is too long #loc -enumerated.constant.naming.convention.problem.descriptor.regex.mismatch=Enumerated constant #ref doesn''t match regex ''{0}'' #loc -instance.method.name.convention.problem.descriptor.short=Instance method name #ref is too short #loc -instance.method.name.convention.problem.descriptor.long=Instance method name #ref is too long #loc -instance.method.name.convention.problem.descriptor.regex.mismatch=Instance method name #ref doesn''t match regex ''{0}'' #loc -instance.variable.name.convention.problem.descriptor.short=Instance field name #ref is too short #loc -instance.variable.name.convention.problem.descriptor.long=Instance field name #ref is too long #loc -instance.variable.name.convention.problem.descriptor.regex.mismatch=Instance field #ref doesn''t match regex ''{0}'' #loc -interface.name.convention.problem.descriptor.short=Interface name #ref is too short #loc -interface.name.convention.problem.descriptor.long=Interface name #ref is too long #loc -interface.name.convention.problem.descriptor.regex.mismatch=Interface name #ref doesn''t match regex ''{0}'' #loc -junit.abstract.test.class.naming.convention.problem.descriptor.short=Abstract JUnit test class name #ref is too short #loc -junit.abstract.test.class.naming.convention.problem.descriptor.long=Abstract JUnit test class name #ref is too long #loc -junit.abstract.test.class.naming.convention.problem.descriptor.regex.mismatch=Abstract JUnit test class name #ref doesn''t match regex ''{0}'' #loc -junit.test.class.naming.convention.problem.descriptor.short=JUnit test class name #ref is too short #loc -junit.test.class.naming.convention.problem.descriptor.long=JUnit test class name #ref is too long #loc -junit.test.class.naming.convention.problem.descriptor.regex.mismatch=JUnit test class name #ref doesn''t match regex ''{0}'' #loc -local.variable.naming.convention.problem.descriptor.short=Local variable name #ref is too short #loc -local.variable.naming.convention.problem.descriptor.long=Local variable name #ref is too long #loc -local.variable.naming.convention.problem.descriptor.regex.mismatch=Local variable name #ref doesn''t match regex ''{0}'' #loc local.variable.naming.convention.ignore.option=Ignore for-loop parameters local.variable.naming.convention.ignore.catch.option=Ignore 'catch' block parameters method.names.differ.only.by.case.problem.descriptor=Method name #ref and method name ''{0}'' differ only by case #loc parameter.name.differs.from.overridden.parameter.ignore.character.option=Ignore if overridden parameter contains only one character parameter.name.differs.from.overridden.parameter.ignore.library.option=Ignore if overridden parameter is from a library parameter.name.differs.from.overridden.parameter.problem.descriptor=Parameter name #ref is different from parameter ''{0}'' overridden #loc -parameter.naming.convention.problem.descriptor.short=Parameter name #ref is too short #loc -parameter.naming.convention.problem.descriptor.long=Parameter name #ref is too long #loc -parameter.naming.convention.problem.descriptor.regex.mismatch=Parameter name #ref doesn''t match regex ''{0}'' #loc questionable.name.column.title=Name standard.variable.names.problem.descriptor=Variable named #ref doesn''t have type ''{0}'' #loc standard.variable.names.problem.descriptor2=Variable named #ref doesn''t have type ''{0}'' or ''{1}'' #loc standard.variable.names.ignore.override.option=Ignore for parameter names identical to super method parameters -static.method.naming.convention.problem.descriptor.short='static' method name #ref is too short #loc -static.method.naming.convention.problem.descriptor.long='static' method name #ref is too long #loc -static.method.naming.convention.problem.descriptor.regex.mismatch=''static'' method name #ref doesn''t match regex ''{0}'' #loc -static.variable.naming.convention.problem.descriptor.short='static' field name #ref is too short #loc -static.variable.naming.convention.problem.descriptor.long='static' field name #ref is too long #loc -static.variable.naming.convention.problem.descriptor.regex.mismatch=''static'' field #ref doesn''t match regex ''{0}'' #loc static.variable.naming.convention.mutable.option=Check 'static final' fields with a mutable type -type.parameter.naming.convention.problem.descriptor.short=Type parameter name #ref is too short #loc -type.parameter.naming.convention.problem.descriptor.long=Type parameter name #ref is too long #loc boolean.method.name.must.start.with.question.table.column.name=Boolean method name prefix conditional.expression.with.identical.branches.collapse.quickfix=Collapse conditional expression confusing.else.unwrap.quickfix=Remove redundant 'else' @@ -2072,9 +2044,7 @@ lambda.parameter.hides.member.variable.problem.descriptor=Lambda parameter #ref is too short #loc -native.method.naming.convention.problem.descriptor.long='native' method name #ref is too long #loc -native.method.naming.convention.problem.descriptor.regex.mismatch=''native'' method name #ref doesn''t match regex ''{0}'' #loc +native.method.naming.convention.element.description='native' method use.of.obsolete.date.time.api.display.name=Use of obsolete date-time API use.of.obsolete.date.time.api.problem.descriptor=Obsolete date-time type #ref used #loc warn.on.label=Warn on: @@ -2102,13 +2072,9 @@ property.value.set.to.itself.display.name=Property value set to itself equals.with.itself.display.name='equals()' called on itself equals.with.itself.problem.descriptor=Identical qualifier and argument to #ref() call junit4.method.naming.convention.display.name=JUnit 4 test method naming convention -junit4.method.naming.convention.problem.descriptor.short=JUnit 4 test method name #ref is too short ({0} < {1}) #loc -junit4.method.naming.convention.problem.descriptor.long=JUnit 4 test method name #ref is too long ({0} > {1}) #loc -junit4.method.naming.convention.problem.descriptor.regex.mismatch=JUnit 4 test method name #ref doesn''t match regex ''{0}'' #loc +junit4.method.naming.convention.element.description=JUnit 4 test method junit3.method.naming.convention.display.name=JUnit 3 test method naming convention -junit3.method.naming.convention.problem.descriptor.short=JUnit 3 test method name #ref is too short ({0} < {1}) #loc -junit3.method.naming.convention.problem.descriptor.long=JUnit 3 test method name #ref is too long ({0} > {1}) #loc -junit3.method.naming.convention.problem.descriptor.regex.mismatch=JUnit 3 test method name #ref doesn''t match regex ''{0}'' #loc +junit3.method.naming.convention.element.description=JUnit 3 test method introduce.holder.class.quickfix=Introduce holder class double.brace.initialization.display.name=Double brace initialization double.brace.initialization.quickfix=Replace with regular initialization @@ -2155,9 +2121,7 @@ extends.throwable.display.name=Class directly extends 'java.lang.Throwable' anonymous.extends.throwable.problem.descriptor=Anonymous class directly extends 'java.lang.Throwable' #loc extends.throwable.problem.descriptor=class #ref directly extends 'java.lang.Throwable' #loc lambda.parameter.naming.convention.display.name=Lambda parameter naming convention -lambda.parameter.naming.convention.problem.descriptor.short=Lambda parameter name #ref is too short #loc -lambda.parameter.naming.convention.problem.descriptor.long=Lambda parameter name #ref is too long #loc -lambda.parameter.naming.convention.problem.descriptor.regex.mismatch=Lambda parameter name #ref doesn''t match regex ''{0}'' #loc +lambda.parameter.naming.convention.element.description=Lambda parameter assert.message.not.string.display.name='assert' message is not a String assert.message.of.type.boolean.problem.descriptor=''assert'' message of type ''{0}'' #loc assert.message.not.string.only.warn.boolean.option=Only warn when 'assert' message is boolean or java.lang.Boolean diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspectionBase.java index 8f27342d8d2b..5cac782a6bf8 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit3MethodNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -39,19 +39,8 @@ public class JUnit3MethodNamingConventionInspectionBase extends ConventionInspec } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String methodName = (String)infos[0]; - final int length = methodName.length(); - if (length < getMinLength()) { - return InspectionGadgetsBundle.message("junit3.method.naming.convention.problem.descriptor.short", - Integer.valueOf(length), Integer.valueOf(getMinLength())); - } - else if (length > getMaxLength()) { - return InspectionGadgetsBundle.message("junit3.method.naming.convention.problem.descriptor.long", - Integer.valueOf(length), Integer.valueOf(getMaxLength())); - } - return InspectionGadgetsBundle.message("junit3.method.naming.convention.problem.descriptor.regex.mismatch", getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("junit3.method.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspectionBase.java index eb0f3d7b91c7..07d5ecfb455d 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnit4MethodNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -39,19 +39,8 @@ public class JUnit4MethodNamingConventionInspectionBase extends ConventionInspec } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String methodName = (String)infos[0]; - final int length = methodName.length(); - if (length < getMinLength()) { - return InspectionGadgetsBundle.message("junit4.method.naming.convention.problem.descriptor.short", - Integer.valueOf(length), Integer.valueOf(getMinLength())); - } - else if (length > getMaxLength()) { - return InspectionGadgetsBundle.message("junit4.method.naming.convention.problem.descriptor.long", - Integer.valueOf(length), Integer.valueOf(getMaxLength())); - } - return InspectionGadgetsBundle.message("junit4.method.naming.convention.problem.descriptor.regex.mismatch", getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("junit4.method.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnitAbstractTestClassNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnitAbstractTestClassNamingConventionInspectionBase.java index fce2f99b4b10..091fe4e5ad8c 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnitAbstractTestClassNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnitAbstractTestClassNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -42,20 +42,8 @@ public class JUnitAbstractTestClassNamingConventionInspectionBase extends Conven } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String className = (String)infos[0]; - if (className.length() < getMinLength()) { - return InspectionGadgetsBundle.message( - "junit.abstract.test.class.naming.convention.problem.descriptor.short"); - } - else if (className.length() > getMaxLength()) { - return InspectionGadgetsBundle.message( - "junit.abstract.test.class.naming.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message( - "junit.abstract.test.class.naming.convention.problem.descriptor.regex.mismatch", - getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("junit.abstract.test.class.naming.convention.element.description"); } @Override @@ -87,9 +75,8 @@ public class JUnitAbstractTestClassNamingConventionInspectionBase extends Conven return; } - PsiClass aClass = (PsiClass)element; - if (aClass.isInterface() || aClass.isEnum() || - aClass.isAnnotationType()) { + final PsiClass aClass = (PsiClass)element; + if (aClass.isInterface() || aClass.isEnum() || aClass.isAnnotationType()) { return; } if (aClass instanceof PsiTypeParameter) { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnitTestClassNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnitTestClassNamingConventionInspectionBase.java index cbbd14eab21b..c58a2e8d6f95 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnitTestClassNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/junit/JUnitTestClassNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,20 +40,8 @@ public class JUnitTestClassNamingConventionInspectionBase extends ConventionInsp } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String className = (String)infos[0]; - if (className.length() < getMinLength()) { - return InspectionGadgetsBundle.message( - "junit.test.class.naming.convention.problem.descriptor.short"); - } - else if (className.length() > getMaxLength()) { - return InspectionGadgetsBundle.message( - "junit.test.class.naming.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message( - "junit.test.class.naming.convention.problem.descriptor.regex.mismatch", - getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("junit.test.class.naming.convention.element.description"); } @Override @@ -84,9 +72,8 @@ public class JUnitTestClassNamingConventionInspectionBase extends ConventionInsp return; } - PsiClass aClass = (PsiClass)element; - if (aClass.isInterface() || aClass.isEnum() || - aClass.isAnnotationType()) { + final PsiClass aClass = (PsiClass)element; + if (aClass.isInterface() || aClass.isEnum() || aClass.isAnnotationType()) { return; } if (aClass instanceof PsiTypeParameter) { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/AbstractClassNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/AbstractClassNamingConventionInspectionBase.java index 5dd3cfe2f1fb..52852a254ffe 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/AbstractClassNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/AbstractClassNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -39,17 +39,8 @@ public class AbstractClassNamingConventionInspectionBase extends ConventionInspe } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String className = (String)infos[0]; - if (className.length() < getMinLength()) { - return InspectionGadgetsBundle.message("abstract.class.name.convention.problem.descriptor.short"); - } - else if (className.length() > getMaxLength()) { - return InspectionGadgetsBundle.message("abstract.class.name.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message("abstract.class.name.convention.problem.descriptor.regex.mismatch", - getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("abstract.class.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/AnnotationNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/AnnotationNamingConventionInspectionBase.java index 2df5cac1c55d..95ed4c0655cf 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/AnnotationNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/AnnotationNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,20 +37,8 @@ public class AnnotationNamingConventionInspectionBase extends ConventionInspecti } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String annotationName = (String)infos[0]; - if (annotationName.length() < getMinLength()) { - return InspectionGadgetsBundle.message( - "annotation.naming.convention.problem.descriptor.short"); - } - else if (annotationName.length() > getMaxLength()) { - return InspectionGadgetsBundle.message( - "annotation.naming.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message( - "annotation.naming.convention.problem.descriptor.regex.mismatch", - getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("annotation.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ClassNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ClassNamingConventionInspectionBase.java index 0b4e766d58d4..f901a223fde6 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ClassNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ClassNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -39,20 +39,8 @@ public class ClassNamingConventionInspectionBase extends ConventionInspection { } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String className = (String)infos[0]; - if (className.length() < getMinLength()) { - return InspectionGadgetsBundle.message( - "class.name.convention.problem.descriptor.short"); - } - else if (className.length() > getMaxLength()) { - return InspectionGadgetsBundle.message( - "class.name.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message( - "class.name.convention.problem.descriptor.regex.mismatch", - getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("class.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ConstantNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ConstantNamingConventionInspectionBase.java index 3ae903515ab6..8889bde3fb63 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ConstantNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ConstantNamingConventionInspectionBase.java @@ -43,16 +43,8 @@ public class ConstantNamingConventionInspectionBase extends ConventionInspection } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String fieldName = (String)infos[0]; - if (fieldName.length() < getMinLength()) { - return InspectionGadgetsBundle.message("constant.naming.convention.problem.descriptor.short"); - } - else if (fieldName.length() > getMaxLength()) { - return InspectionGadgetsBundle.message("constant.naming.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message("constant.naming.convention.problem.descriptor.regex.mismatch", getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("constant.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ConventionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ConventionInspection.java index 7afacaf647fd..e598028c7c91 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ConventionInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ConventionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package com.siyeh.ig.naming; import com.intellij.codeInspection.ui.ConventionOptionsPanel; import com.intellij.openapi.util.InvalidDataException; import com.siyeh.HardcodedMethodConstants; +import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -45,6 +46,24 @@ public abstract class ConventionInspection extends BaseInspection { protected Pattern m_regexPattern = Pattern.compile(m_regex); + @Override + @NotNull + protected final String buildErrorString(Object... infos) { + final String name = (String)infos[0]; + final int length = name.length(); + if (length < getMinLength()) { + return InspectionGadgetsBundle.message("naming.convention.problem.descriptor.short", getElementDescription(), + Integer.valueOf(length), Integer.valueOf(getMinLength())); + } + else if (getMaxLength() > 0 && length > getMaxLength()) { + return InspectionGadgetsBundle.message("naming.convention.problem.descriptor.long", getElementDescription(), + Integer.valueOf(length), Integer.valueOf(getMaxLength())); + } + return InspectionGadgetsBundle.message("naming.convention.problem.descriptor.regex.mismatch", getElementDescription(), getRegex()); + } + + protected abstract String getElementDescription(); + @NonNls protected abstract String getDefaultRegex(); diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/EnumeratedClassNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/EnumeratedClassNamingConventionInspectionBase.java index 09cb8e6b338f..6cbeacd911b4 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/EnumeratedClassNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/EnumeratedClassNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,20 +37,8 @@ public class EnumeratedClassNamingConventionInspectionBase extends ConventionIns } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String className = (String)infos[0]; - if (className.length() < getMinLength()) { - return InspectionGadgetsBundle.message( - "enumerated.class.naming.convention.problem.descriptor.short"); - } - else if (className.length() > getMaxLength()) { - return InspectionGadgetsBundle.message( - "enumerated.class.naming.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message( - "enumerated.class.naming.convention.problem.descriptor.regex.mismatch", - getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("enumerated.class.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/EnumeratedConstantNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/EnumeratedConstantNamingConventionInspectionBase.java index 5cb0ba9fc3dd..e46ab8a8134b 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/EnumeratedConstantNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/EnumeratedConstantNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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,16 +36,8 @@ public class EnumeratedConstantNamingConventionInspectionBase extends Convention } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String fieldName = (String)infos[0]; - if (fieldName.length() < getMinLength()) { - return InspectionGadgetsBundle.message("enumerated.constant.naming.convention.problem.descriptor.short"); - } - else if (fieldName.length() > getMaxLength()) { - return InspectionGadgetsBundle.message("enumerated.constant.naming.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message("enumerated.constant.naming.convention.problem.descriptor.regex.mismatch", getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("enumerated.constant.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionBase.java index 964ce0b0aace..85fe6d20e8ca 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InstanceMethodNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -43,16 +43,8 @@ public class InstanceMethodNamingConventionInspectionBase extends ConventionInsp } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String methodName = (String)infos[0]; - if (methodName.length() < getMinLength()) { - return InspectionGadgetsBundle.message("instance.method.name.convention.problem.descriptor.short"); - } - else if (methodName.length() > getMaxLength()) { - return InspectionGadgetsBundle.message("instance.method.name.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message("instance.method.name.convention.problem.descriptor.regex.mismatch", getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("instance.method.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InstanceVariableNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InstanceVariableNamingConventionInspectionBase.java index 53cac98431a3..88455fdf5b5f 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InstanceVariableNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InstanceVariableNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,20 +38,8 @@ public class InstanceVariableNamingConventionInspectionBase extends ConventionIn } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String fieldName = (String)infos[0]; - if (fieldName.length() < getMinLength()) { - return InspectionGadgetsBundle.message( - "instance.variable.name.convention.problem.descriptor.short"); - } - else if (fieldName.length() > getMaxLength()) { - return InspectionGadgetsBundle.message( - "instance.variable.name.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message( - "instance.variable.name.convention.problem.descriptor.regex.mismatch", - getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("instance.variable.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InterfaceNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InterfaceNamingConventionInspectionBase.java index 9a1049fc3f5e..f811cd6fc7a9 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InterfaceNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/InterfaceNamingConventionInspectionBase.java @@ -37,20 +37,8 @@ public class InterfaceNamingConventionInspectionBase extends ConventionInspectio } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String interfaceName = (String)infos[0]; - if (interfaceName.length() < getMinLength()) { - return InspectionGadgetsBundle.message( - "interface.name.convention.problem.descriptor.short"); - } - else if (interfaceName.length() > getMaxLength()) { - return InspectionGadgetsBundle.message( - "interface.name.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message( - "interface.name.convention.problem.descriptor.regex.mismatch", - getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("interface.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/LambdaParameterNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/LambdaParameterNamingConventionInspectionBase.java index 6434ba6a21bc..1858a29d3983 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/LambdaParameterNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/LambdaParameterNamingConventionInspectionBase.java @@ -46,18 +46,8 @@ public class LambdaParameterNamingConventionInspectionBase extends ConventionIns } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String parameterName = (String)infos[0]; - if (parameterName.length() < getMinLength()) { - return InspectionGadgetsBundle.message("lambda.parameter.naming.convention.problem.descriptor.short"); - } - else if (parameterName.length() > getMaxLength()) { - return InspectionGadgetsBundle.message("lambda.parameter.naming.convention.problem.descriptor.long"); - } - else { - return InspectionGadgetsBundle.message("lambda.parameter.naming.convention.problem.descriptor.regex.mismatch", getRegex()); - } + protected String getElementDescription() { + return InspectionGadgetsBundle.message("lambda.parameter.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/LocalVariableNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/LocalVariableNamingConventionInspectionBase.java index 5f4f13ee4c3c..095cf4bf2ea3 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/LocalVariableNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/LocalVariableNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -39,18 +39,8 @@ public class LocalVariableNamingConventionInspectionBase extends ConventionInspe } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String varName = (String)infos[0]; - if (varName.length() < getMinLength()) { - return InspectionGadgetsBundle.message("local.variable.naming.convention.problem.descriptor.short"); - } - else if (varName.length() > getMaxLength()) { - return InspectionGadgetsBundle.message("local.variable.naming.convention.problem.descriptor.long"); - } - else { - return InspectionGadgetsBundle.message("local.variable.naming.convention.problem.descriptor.regex.mismatch", getRegex()); - } + protected String getElementDescription() { + return InspectionGadgetsBundle.message("local.variable.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/NativeMethodNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/NativeMethodNamingConventionInspectionBase.java index 2231fa152678..8adf90d7f16f 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/NativeMethodNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/NativeMethodNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,16 +40,8 @@ public class NativeMethodNamingConventionInspectionBase extends ConventionInspec } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String methodName = (String)infos[0]; - if (methodName.length() < getMinLength()) { - return InspectionGadgetsBundle.message("native.method.naming.convention.problem.descriptor.short"); - } - else if (methodName.length() > getMaxLength()) { - return InspectionGadgetsBundle.message("native.method.naming.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message("native.method.naming.convention.problem.descriptor.regex.mismatch", getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("native.method.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ParameterNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ParameterNamingConventionInspectionBase.java index 9f57a0dbce96..f06a130ebc1a 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ParameterNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/ParameterNamingConventionInspectionBase.java @@ -43,22 +43,8 @@ public class ParameterNamingConventionInspectionBase extends ConventionInspectio } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String parametername = (String)infos[0]; - if (parametername.length() < getMinLength()) { - return InspectionGadgetsBundle.message( - "parameter.naming.convention.problem.descriptor.short"); - } - else if (parametername.length() > getMaxLength()) { - return InspectionGadgetsBundle.message( - "parameter.naming.convention.problem.descriptor.long"); - } - else { - return InspectionGadgetsBundle.message( - "parameter.naming.convention.problem.descriptor.regex.mismatch", - getRegex()); - } + protected String getElementDescription() { + return InspectionGadgetsBundle.message("parameter.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionBase.java index 3e0d08998ec0..4a0f5b195adb 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/StaticMethodNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,20 +38,8 @@ public class StaticMethodNamingConventionInspectionBase extends ConventionInspec } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String methodName = (String)infos[0]; - if (methodName.length() < getMinLength()) { - return InspectionGadgetsBundle.message( - "static.method.naming.convention.problem.descriptor.short"); - } - else if (methodName.length() > getMaxLength()) { - return InspectionGadgetsBundle.message( - "static.method.naming.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message( - "static.method.naming.convention.problem.descriptor.regex.mismatch", - getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("static.method.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/StaticVariableNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/StaticVariableNamingConventionInspectionBase.java index 55d3c6aa4279..34c689e498d1 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/StaticVariableNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/StaticVariableNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -44,16 +44,8 @@ public class StaticVariableNamingConventionInspectionBase extends ConventionInsp } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String fieldName = (String)infos[0]; - if (fieldName.length() < getMinLength()) { - return InspectionGadgetsBundle.message("static.variable.naming.convention.problem.descriptor.short"); - } - else if (fieldName.length() > getMaxLength()) { - return InspectionGadgetsBundle.message("static.variable.naming.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message("static.variable.naming.convention.problem.descriptor.regex.mismatch", getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("static.variable.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/TypeParameterNamingConventionInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/TypeParameterNamingConventionInspectionBase.java index 4d0e76be1a60..05e715da6ebb 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/TypeParameterNamingConventionInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/naming/TypeParameterNamingConventionInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,20 +38,8 @@ public class TypeParameterNamingConventionInspectionBase extends ConventionInspe } @Override - @NotNull - public String buildErrorString(Object... infos) { - final String parameterName = (String)infos[0]; - if (parameterName.length() < getMinLength()) { - return InspectionGadgetsBundle.message( - "type.parameter.naming.convention.problem.descriptor.short"); - } - else if (parameterName.length() > getMaxLength()) { - return InspectionGadgetsBundle.message( - "type.parameter.naming.convention.problem.descriptor.long"); - } - return InspectionGadgetsBundle.message( - "enumerated.class.naming.convention.problem.descriptor.regex.mismatch", - getRegex()); + protected String getElementDescription() { + return InspectionGadgetsBundle.message("type.parameter.naming.convention.element.description"); } @Override diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/abstract_class_naming_convention/Simple.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/abstract_class_naming_convention/Simple.java index fdb4e7533b7d..09c97a23d537 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/abstract_class_naming_convention/Simple.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/abstract_class_naming_convention/Simple.java @@ -1,4 +1,4 @@ package com.siyeh.igtest.naming.abstract_class_naming_convention; -public abstract class Simple { +public abstract class Simple { } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/constant_naming_convention/ConstantNamingConvention.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/constant_naming_convention/ConstantNamingConvention.java index c6831a9181e6..c142d1c4acda 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/constant_naming_convention/ConstantNamingConvention.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/constant_naming_convention/ConstantNamingConvention.java @@ -2,6 +2,6 @@ package com.siyeh.igtest.naming.constant_naming_convention; class ConstantNamingConvention { static final String A_B_C_D3 = ""; - static final String a = ""; - static final String aaaaaa = ""; + static final String a = ""; + static final String aaaaaa = ""; } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/constant_naming_convention/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/constant_naming_convention/expected.xml deleted file mode 100644 index 18984482ee14..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/constant_naming_convention/expected.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - ConstantNamingConvention.java - 5 - Constant naming convention - Constant name <code>a</code> is too short #loc - - - - ConstantNamingConvention.java - 6 - Constant naming convention - Constant <code>aaaaaa</code> doesn't match regex '[A-Z][A-Z_\d]*' #loc - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/enumerated_constant_naming_convention/EnumeratedConstantNamingConvention.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/enumerated_constant_naming_convention/EnumeratedConstantNamingConvention.java index e09cd6c95f1b..f5584ef2adcd 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/enumerated_constant_naming_convention/EnumeratedConstantNamingConvention.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/enumerated_constant_naming_convention/EnumeratedConstantNamingConvention.java @@ -2,6 +2,6 @@ package com.siyeh.igtest.naming.enumerated_constant_naming_convention; enum EnumeratedConstantNamingConvention { A_B_C, - A, - aaaaaa + A, + aaaaaa } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/enumerated_constant_naming_convention/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/enumerated_constant_naming_convention/expected.xml deleted file mode 100644 index 7c95a6f2665c..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/enumerated_constant_naming_convention/expected.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - EnumeratedConstantNamingConvention.java - 5 - Enumerated constant naming convention - Enumerated constant name <code>A</code> is too short #loc - - - - EnumeratedConstantNamingConvention.java - 6 - Enumerated constant naming convention - Enumerated constant <code>aaaaaa</code> doesn't match regex '[A-Z][A-Z_\d]*' #loc - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/instance_method_naming_convention/InstanceMethodNamingConvention.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/instance_method_naming_convention/InstanceMethodNamingConvention.java index c38ed4339276..8cd5980045a2 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/instance_method_naming_convention/InstanceMethodNamingConvention.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/instance_method_naming_convention/InstanceMethodNamingConvention.java @@ -12,12 +12,12 @@ public class InstanceMethodNamingConvention implements Runnable } - public void foo() + public void foo() { } - public void methodNameTooLoooooooooooooooooooooooooooooooooooooooooooooong() + public void methodNameTooLoooooooooooooooooooooooooooooooooooooooooooooong() { } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/lambda_parameter_naming_convention/LambdaParameterNamingConvention.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/lambda_parameter_naming_convention/LambdaParameterNamingConvention.java index 02fd7e3fd974..f0f72a7fc9c9 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/lambda_parameter_naming_convention/LambdaParameterNamingConvention.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/lambda_parameter_naming_convention/LambdaParameterNamingConvention.java @@ -2,7 +2,7 @@ public class LambdaParameterNamingConvention { void m(int a) {} void n(int abcd) { - F f = (i) -> 10; + F f = (i) -> 10; F g = abc -> 12; } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/native_method_naming_convention/NativeMethodNamingConvention.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/native_method_naming_convention/NativeMethodNamingConvention.java index 9b8a8e66d289..4e7728d060c3 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/native_method_naming_convention/NativeMethodNamingConvention.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/native_method_naming_convention/NativeMethodNamingConvention.java @@ -21,13 +21,13 @@ public class NativeMethodNamingConvention implements Runnable public native void methodNameEndingIn2(); - public native void foo(); + public native void foo(); - public native void methodNameTooLoooooooooooooooooooooooooooooooooooooooooooooong(); + public native void methodNameTooLoooooooooooooooooooooooooooooooooooooooooooooong(); public native void run(); private void a() {} - public static native void b(); + public static native void b(); } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/parameter_naming_convention/ParameterNamingConvention.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/parameter_naming_convention/ParameterNamingConvention.java index d359edfc1197..5315ce906113 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/parameter_naming_convention/ParameterNamingConvention.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/parameter_naming_convention/ParameterNamingConvention.java @@ -2,13 +2,13 @@ package com.siyeh.igtest.naming.parameter_naming_convention; public class ParameterNamingConvention { - void m(int a) {} + void m(int a) {} void n(int abcd) { F f = (i) -> 10; } interface F { - int a(int i); + int a(int i); } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/static_method_naming_convention/StaticMethodNamingConvention.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/static_method_naming_convention/StaticMethodNamingConvention.java index a8b22d340e7f..8c20a5669327 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/static_method_naming_convention/StaticMethodNamingConvention.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/naming/static_method_naming_convention/StaticMethodNamingConvention.java @@ -12,12 +12,12 @@ public class StaticMethodNamingConvention } - public static void foo() + public static void foo() { } - public static void methodNameTooLoooooooooooooooooooooooooooooooooooooooooooooong() + public static void methodNameTooLoooooooooooooooooooooooooooooooooooooooooooooong() { } diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/ConstantNamingConventionInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/ConstantNamingConventionInspectionTest.java index 349e6e82d6d6..42d4a45413f9 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/ConstantNamingConventionInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/ConstantNamingConventionInspectionTest.java @@ -1,10 +1,18 @@ package com.siyeh.ig.naming; -import com.siyeh.ig.IGInspectionTestCase; +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; -public class ConstantNamingConventionInspectionTest extends IGInspectionTestCase { +public class ConstantNamingConventionInspectionTest extends LightInspectionTestCase { - public void test() throws Exception { - doTest("com/siyeh/igtest/naming/constant_naming_convention", new ConstantNamingConventionInspection()); + public void testConstantNamingConvention() { + doTest(); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + return new ConstantNamingConventionInspection(); } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/EnumeratedConstantNamingConventionInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/EnumeratedConstantNamingConventionInspectionTest.java index 9545709ee10e..06ab04b6e5e0 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/EnumeratedConstantNamingConventionInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/naming/EnumeratedConstantNamingConventionInspectionTest.java @@ -1,10 +1,18 @@ package com.siyeh.ig.naming; -import com.siyeh.ig.IGInspectionTestCase; +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; -public class EnumeratedConstantNamingConventionInspectionTest extends IGInspectionTestCase { +public class EnumeratedConstantNamingConventionInspectionTest extends LightInspectionTestCase { - public void test() throws Exception { - doTest("com/siyeh/igtest/naming/enumerated_constant_naming_convention", new EnumeratedConstantNamingConventionInspection()); + public void testEnumeratedConstantNamingConvention() { + doTest(); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + return new EnumeratedConstantNamingConventionInspection(); } } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodMergingContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodMergingContributor.java index 365d88573313..394956f4b62b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodMergingContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodMergingContributor.java @@ -17,7 +17,6 @@ package org.jetbrains.plugins.groovy.lang.completion; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiParameter; import com.intellij.psi.PsiType; @@ -48,7 +47,7 @@ public class GrMethodMergingContributor extends CompletionContributor { final ArrayList allMethods = new ArrayList(); for (LookupElement item : items) { Object o = item.getPsiElement(); - if (item.getUserData(LookupItem.FORCE_SHOW_SIGNATURE_ATTR) != null || !(o instanceof PsiMethod)) { + if (item.getUserData(JavaCompletionUtil.FORCE_SHOW_SIGNATURE_ATTR) != null || !(o instanceof PsiMethod)) { return AutoCompletionDecision.SHOW_LOOKUP; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java index 0c32878b5853..40b7ae0d1537 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java @@ -22,7 +22,6 @@ import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.completion.originInfo.OriginInfoProvider; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; @@ -450,7 +449,7 @@ public class GroovyCompletionUtil { return !hasAccessibleConstructors && (hasParameters || hasSetters); } - public static void addImportForItem(PsiFile file, int startOffset, LookupItem item) throws IncorrectOperationException { + public static void addImportForItem(PsiFile file, int startOffset, LookupElement item) throws IncorrectOperationException { PsiDocumentManager.getInstance(file.getProject()).commitAllDocuments(); Object o = item.getObject(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java index dd8262ba350e..68f4d515c4ea 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java @@ -18,7 +18,6 @@ package org.jetbrains.plugins.groovy.lang.completion; import com.intellij.codeInsight.TailType; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.codeInsight.lookup.PsiTypeLookupItem; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.openapi.editor.Document; @@ -185,7 +184,7 @@ public class GroovySmartCompletionContributor extends CompletionContributor { editor.getCaretModel().moveToOffset(context.getTailOffset()); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); - GroovyCompletionUtil.addImportForItem(context.getFile(), context.getStartOffset(), ((LookupItem)item)); + GroovyCompletionUtil.addImportForItem(context.getFile(), context.getStartOffset(), item); } }); result.addElement(item); @@ -293,9 +292,9 @@ public class GroovySmartCompletionContributor extends CompletionContributor { final PsiType _type = GenericsUtil.eliminateWildcards(type); final PsiTypeLookupItem item = PsiTypeLookupItem.createLookupItem(_type, place, PsiTypeLookupItem.isDiamond(_type), ChooseTypeExpression.IMPORT_FIXER).setShowPackage(); if (item.getObject() instanceof PsiClass) { - item.setInsertHandler(new InsertHandler() { + item.setInsertHandler(new InsertHandler() { @Override - public void handleInsert(InsertionContext context, LookupItem item) { + public void handleInsert(InsertionContext context, LookupElement item) { GroovyCompletionUtil.addImportForItem(context.getFile(), context.getStartOffset(), item); } }); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/AfterNewClassInsertHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/AfterNewClassInsertHandler.java index 76bb684cafd3..e873f9631acb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/AfterNewClassInsertHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/handlers/AfterNewClassInsertHandler.java @@ -22,9 +22,8 @@ import com.intellij.codeInsight.completion.InsertHandler; import com.intellij.codeInsight.completion.InsertionContext; import com.intellij.codeInsight.completion.JavaCompletionFeatures; import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler; -import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.featureStatistics.FeatureUsageTracker; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; @@ -36,9 +35,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; /** * @author Maxim.Medvedev */ -public class AfterNewClassInsertHandler implements InsertHandler> { - private static final Logger LOG = Logger.getInstance(AfterNewClassInsertHandler.class); - +public class AfterNewClassInsertHandler implements InsertHandler { private final PsiClassType myClassType; private final boolean myTriggerFeature; @@ -48,7 +45,7 @@ public class AfterNewClassInsertHandler implements InsertHandler item) { + public void handleInsert(final InsertionContext context, LookupElement item) { final PsiClassType.ClassResolveResult resolveResult = myClassType.resolveGenerics(); final PsiClass psiClass = resolveResult.getElement(); if (psiClass == null || !psiClass.isValid()) { diff --git a/plugins/testng/src/com/theoryinpractice/testng/inspection/TestNGMethodNamingConventionInspection.java b/plugins/testng/src/com/theoryinpractice/testng/inspection/TestNGMethodNamingConventionInspection.java index 2cc894faf064..4ac61f402c7d 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/inspection/TestNGMethodNamingConventionInspection.java +++ b/plugins/testng/src/com/theoryinpractice/testng/inspection/TestNGMethodNamingConventionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,18 +38,9 @@ public class TestNGMethodNamingConventionInspection extends ConventionInspection return "TestNG test method naming convention"; } - @NotNull @Override - protected String buildErrorString(Object... infos) { - final String methodName = (String)infos[0]; - final int length = methodName.length(); - if (length < getMinLength()) { - return "TestNG test method name #ref is too short (" + length + " < " + getMinLength() + ") #loc"; - } - else if (length > getMaxLength()) { - return "TestNG test method name #ref is too long (" + length + " > " + getMaxLength() + ") #loc"; - } - return "JUnit4 test method name #ref doesn't match regex '{0}' #loc"; + protected String getElementDescription() { + return "TestNG test method"; } @Override diff --git a/python/helpers/python-skeletons/collections.py b/python/helpers/python-skeletons/collections.py index 4647a8ff7495..97f8a26cdcff 100644 --- a/python/helpers/python-skeletons/collections.py +++ b/python/helpers/python-skeletons/collections.py @@ -5,6 +5,19 @@ import sys import collections +class Iterable(object): + def __init__(self): + """ + :rtype: collections.Iterable[T] + """ + pass + + def __iter__(self): + """ + :rtype: collections.Iterator[T] + """ + + class Iterator(collections.Iterable): def __init__(self): """ diff --git a/python/resources/fileTemplates/internal/Python Unit Test.py.ft b/python/resources/fileTemplates/internal/Python Unit Test.py.ft index 1b20ae4f1c00..432d1ea17ee0 100644 --- a/python/resources/fileTemplates/internal/Python Unit Test.py.ft +++ b/python/resources/fileTemplates/internal/Python Unit Test.py.ft @@ -1,4 +1,3 @@ - import unittest class MyTestCase(unittest.TestCase): diff --git a/python/src/com/jetbrains/python/codeInsight/PyTypingTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/PyTypingTypeProvider.java index 05920396d020..9528ff5df6b8 100644 --- a/python/src/com/jetbrains/python/codeInsight/PyTypingTypeProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/PyTypingTypeProvider.java @@ -43,12 +43,21 @@ import java.util.regex.Pattern; */ public class PyTypingTypeProvider extends PyTypeProviderBase { public static final Pattern TYPE_COMMENT_PATTERN = Pattern.compile("# *type: *(.*)"); - private static ImmutableMap BUILTIN_COLLECTIONS = ImmutableMap.builder() + private static ImmutableMap COLLECTION_CLASSES = ImmutableMap.builder() .put("typing.List", "list") .put("typing.Dict", "dict") .put("typing.Set", PyNames.SET) .put("typing.FrozenSet", "frozenset") .put("typing.Tuple", PyNames.TUPLE) + .put("typing.Iterable", PyNames.COLLECTIONS + "." + PyNames.ITERABLE) + .put("typing.Iterator", PyNames.COLLECTIONS + "." + PyNames.ITERATOR) + .put("typing.Container", PyNames.COLLECTIONS + "." + PyNames.CONTAINER) + .put("typing.Sequence", PyNames.COLLECTIONS + "." + PyNames.SEQUENCE) + .put("typing.MutableSequence", PyNames.COLLECTIONS + "." + "MutableSequence") + .put("typing.Mapping", PyNames.COLLECTIONS + "." + PyNames.MAPPING) + .put("typing.MutableMapping", PyNames.COLLECTIONS + "." + "MutableMapping") + .put("typing.AbstractSet", PyNames.COLLECTIONS + "." + "Set") + .put("typing.MutableSet", PyNames.COLLECTIONS + "." + "MutableSet") .build(); private static ImmutableSet GENERIC_CLASSES = ImmutableSet.builder() @@ -457,7 +466,7 @@ public class PyTypingTypeProvider extends PyTypeProviderBase { @Nullable private static PyType getBuiltinCollection(@NotNull PyExpression expression, @NotNull TypeEvalContext context) { final String collectionName = resolveToQualifiedName(expression, context); - final String builtinName = BUILTIN_COLLECTIONS.get(collectionName); + final String builtinName = COLLECTION_CLASSES.get(collectionName); return builtinName != null ? PyTypeParser.getTypeByName(expression, builtinName) : null; } diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibCanonicalPathProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibCanonicalPathProvider.java index 16f64dc24b69..9a5b6f354496 100644 --- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibCanonicalPathProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibCanonicalPathProvider.java @@ -38,7 +38,7 @@ public class PyStdlibCanonicalPathProvider implements PyCanonicalPathProvider { if (qName.getComponentCount() > 0) { final List components = qName.getComponents(); final String head = components.get(0); - if (head.equals("_abcoll") || head.equals("_collections")) { + if (head.equals("_abcoll") || head.equals("_collections") || head.equals("_collections_abc")) { components.set(0, "collections"); return QualifiedName.fromComponents(components); } diff --git a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java index c14ddd476427..c32f047ea722 100644 --- a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java @@ -534,10 +534,18 @@ public class PyUnresolvedReferencesInspection extends PyInspection { return; } addCreateMemberFromUsageFixes(type, reference, refText, actions); - if (type instanceof PyClassTypeImpl) { + if (type instanceof PyClassType) { if (reference instanceof PyOperatorReference) { + String className = type.getName(); + final PyClassType classType = (PyClassType)type; + if (classType.isDefinition()) { + final PyClassLikeType metaClassType = classType.getMetaClassType(myTypeEvalContext, true); + if (metaClassType != null) { + className = metaClassType.getName(); + } + } description = PyBundle.message("INSP.unresolved.operator.ref", - type.getName(), refName, + className, refName, ((PyOperatorReference)reference).getReadableOperatorName()); } else { diff --git a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java index cafb01e4cf2a..59b02eee5c7a 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java @@ -362,7 +362,7 @@ public class PyTargetExpressionImpl extends PyBaseElementImpl results = new ArrayList(); if (object != null && name != null) { final TypeEvalContext typeEvalContext = myContext.getTypeEvalContext(); - final PyType type = typeEvalContext.getType(object); + PyType type = typeEvalContext.getType(object); typeEvalContext.trace("Side text is %s, type is %s", object.getText(), type); + if (type instanceof PyClassLikeType) { + if (((PyClassLikeType)type).isDefinition()) { + type = ((PyClassLikeType)type).getMetaClassType(typeEvalContext, true); + } + } if (type != null) { List res = type.resolveMember(name, object, AccessDirection.of(myElement), myContext); if (res != null && res.size() > 0) { diff --git a/python/src/com/jetbrains/python/sdk/PySdkUpdater.java b/python/src/com/jetbrains/python/sdk/PySdkUpdater.java index ae0985d973b0..01728cd0b306 100644 --- a/python/src/com/jetbrains/python/sdk/PySdkUpdater.java +++ b/python/src/com/jetbrains/python/sdk/PySdkUpdater.java @@ -18,7 +18,6 @@ package com.jetbrains.python.sdk; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkModificator; -import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; @@ -90,7 +89,7 @@ public abstract class PySdkUpdater { return sdk; } else { - return new ProjectJdkImpl(getHomePath(), PythonSdkType.getInstance()); + throw new PySdkNotFoundException(); } } @@ -143,4 +142,6 @@ public abstract class PySdkUpdater { public interface SdkModificationProcessor { void process(@NotNull Sdk sdk, @NotNull SdkModificator sdkModificator); } + + public class PySdkNotFoundException extends RuntimeException {} } diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java index 77a9f0e2ae25..67e7326ad809 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java @@ -530,14 +530,18 @@ public class PythonSdkType extends SdkType { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - final boolean success = doSetupSdkPaths(project, ownerComponent, PySdkUpdater.fromSdkPath(sdk.getHomePath())); + try { + final boolean success = doSetupSdkPaths(project, ownerComponent, PySdkUpdater.fromSdkPath(sdk.getHomePath())); - if (!success) { - Messages.showErrorDialog( - project, - PyBundle.message("MSG.cant.setup.sdk.$0", FileUtil.toSystemDependentName(sdk.getSdkModificator().getHomePath())), - PyBundle.message("MSG.title.bad.sdk") - ); + if (!success) { + Messages.showErrorDialog( + project, + PyBundle.message("MSG.cant.setup.sdk.$0", FileUtil.toSystemDependentName(sdk.getSdkModificator().getHomePath())), + PyBundle.message("MSG.title.bad.sdk") + ); + } + } catch (PySdkUpdater.PySdkNotFoundException e) { + // sdk was removed from sdk table so no need to setup paths } } }, ModalityState.NON_MODAL); diff --git a/python/testData/MockSdk3.4/Lib/_collections_abc.py b/python/testData/MockSdk3.4/Lib/_collections_abc.py new file mode 100644 index 000000000000..faa1ff22ff40 --- /dev/null +++ b/python/testData/MockSdk3.4/Lib/_collections_abc.py @@ -0,0 +1,734 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Abstract Base Classes (ABCs) for collections, according to PEP 3119. + +Unit tests are in test_collections. +""" + +from abc import ABCMeta, abstractmethod +import sys + +__all__ = ["Hashable", "Iterable", "Iterator", + "Sized", "Container", "Callable", + "Set", "MutableSet", + "Mapping", "MutableMapping", + "MappingView", "KeysView", "ItemsView", "ValuesView", + "Sequence", "MutableSequence", + "ByteString", + ] + +# This module has been renamed from collections.abc to _collections_abc to +# speed up interpreter startup. Some of the types such as MutableMapping are +# required early but collections module imports a lot of other modules. +# See issue #19218 +__name__ = "collections.abc" + +# Private list of types that we want to register with the various ABCs +# so that they will pass tests like: +# it = iter(somebytearray) +# assert isinstance(it, Iterable) +# Note: in other implementations, these types many not be distinct +# and they make have their own implementation specific types that +# are not included on this list. +bytes_iterator = type(iter(b'')) +bytearray_iterator = type(iter(bytearray())) +#callable_iterator = ??? +dict_keyiterator = type(iter({}.keys())) +dict_valueiterator = type(iter({}.values())) +dict_itemiterator = type(iter({}.items())) +list_iterator = type(iter([])) +list_reverseiterator = type(iter(reversed([]))) +range_iterator = type(iter(range(0))) +set_iterator = type(iter(set())) +str_iterator = type(iter("")) +tuple_iterator = type(iter(())) +zip_iterator = type(iter(zip())) +## views ## +dict_keys = type({}.keys()) +dict_values = type({}.values()) +dict_items = type({}.items()) +## misc ## +mappingproxy = type(type.__dict__) + + +### ONE-TRICK PONIES ### + +class Hashable(metaclass=ABCMeta): + + __slots__ = () + + @abstractmethod + def __hash__(self): + return 0 + + @classmethod + def __subclasshook__(cls, C): + if cls is Hashable: + for B in C.__mro__: + if "__hash__" in B.__dict__: + if B.__dict__["__hash__"]: + return True + break + return NotImplemented + + +class Iterable(metaclass=ABCMeta): + + __slots__ = () + + @abstractmethod + def __iter__(self): + while False: + yield None + + @classmethod + def __subclasshook__(cls, C): + if cls is Iterable: + if any("__iter__" in B.__dict__ for B in C.__mro__): + return True + return NotImplemented + + +class Iterator(Iterable): + + __slots__ = () + + @abstractmethod + def __next__(self): + 'Return the next item from the iterator. When exhausted, raise StopIteration' + raise StopIteration + + def __iter__(self): + return self + + @classmethod + def __subclasshook__(cls, C): + if cls is Iterator: + if (any("__next__" in B.__dict__ for B in C.__mro__) and + any("__iter__" in B.__dict__ for B in C.__mro__)): + return True + return NotImplemented + +Iterator.register(bytes_iterator) +Iterator.register(bytearray_iterator) +#Iterator.register(callable_iterator) +Iterator.register(dict_keyiterator) +Iterator.register(dict_valueiterator) +Iterator.register(dict_itemiterator) +Iterator.register(list_iterator) +Iterator.register(list_reverseiterator) +Iterator.register(range_iterator) +Iterator.register(set_iterator) +Iterator.register(str_iterator) +Iterator.register(tuple_iterator) +Iterator.register(zip_iterator) + +class Sized(metaclass=ABCMeta): + + __slots__ = () + + @abstractmethod + def __len__(self): + return 0 + + @classmethod + def __subclasshook__(cls, C): + if cls is Sized: + if any("__len__" in B.__dict__ for B in C.__mro__): + return True + return NotImplemented + + +class Container(metaclass=ABCMeta): + + __slots__ = () + + @abstractmethod + def __contains__(self, x): + return False + + @classmethod + def __subclasshook__(cls, C): + if cls is Container: + if any("__contains__" in B.__dict__ for B in C.__mro__): + return True + return NotImplemented + + +class Callable(metaclass=ABCMeta): + + __slots__ = () + + @abstractmethod + def __call__(self, *args, **kwds): + return False + + @classmethod + def __subclasshook__(cls, C): + if cls is Callable: + if any("__call__" in B.__dict__ for B in C.__mro__): + return True + return NotImplemented + + +### SETS ### + + +class Set(Sized, Iterable, Container): + + """A set is a finite, iterable container. + + This class provides concrete generic implementations of all + methods except for __contains__, __iter__ and __len__. + + To override the comparisons (presumably for speed, as the + semantics are fixed), all you have to do is redefine __le__ and + then the other operations will automatically follow suit. + """ + + __slots__ = () + + def __le__(self, other): + if not isinstance(other, Set): + return NotImplemented + if len(self) > len(other): + return False + for elem in self: + if elem not in other: + return False + return True + + def __lt__(self, other): + if not isinstance(other, Set): + return NotImplemented + return len(self) < len(other) and self.__le__(other) + + def __gt__(self, other): + if not isinstance(other, Set): + return NotImplemented + return other.__lt__(self) + + def __ge__(self, other): + if not isinstance(other, Set): + return NotImplemented + return other.__le__(self) + + def __eq__(self, other): + if not isinstance(other, Set): + return NotImplemented + return len(self) == len(other) and self.__le__(other) + + def __ne__(self, other): + return not (self == other) + + @classmethod + def _from_iterable(cls, it): + '''Construct an instance of the class from any iterable input. + + Must override this method if the class constructor signature + does not accept an iterable for an input. + ''' + return cls(it) + + def __and__(self, other): + if not isinstance(other, Iterable): + return NotImplemented + return self._from_iterable(value for value in other if value in self) + + def isdisjoint(self, other): + 'Return True if two sets have a null intersection.' + for value in other: + if value in self: + return False + return True + + def __or__(self, other): + if not isinstance(other, Iterable): + return NotImplemented + chain = (e for s in (self, other) for e in s) + return self._from_iterable(chain) + + def __sub__(self, other): + if not isinstance(other, Set): + if not isinstance(other, Iterable): + return NotImplemented + other = self._from_iterable(other) + return self._from_iterable(value for value in self + if value not in other) + + def __xor__(self, other): + if not isinstance(other, Set): + if not isinstance(other, Iterable): + return NotImplemented + other = self._from_iterable(other) + return (self - other) | (other - self) + + def _hash(self): + """Compute the hash value of a set. + + Note that we don't define __hash__: not all sets are hashable. + But if you define a hashable set type, its __hash__ should + call this function. + + This must be compatible __eq__. + + All sets ought to compare equal if they contain the same + elements, regardless of how they are implemented, and + regardless of the order of the elements; so there's not much + freedom for __eq__ or __hash__. We match the algorithm used + by the built-in frozenset type. + """ + MAX = sys.maxsize + MASK = 2 * MAX + 1 + n = len(self) + h = 1927868237 * (n + 1) + h &= MASK + for x in self: + hx = hash(x) + h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167 + h &= MASK + h = h * 69069 + 907133923 + h &= MASK + if h > MAX: + h -= MASK + 1 + if h == -1: + h = 590923713 + return h + +Set.register(frozenset) + + +class MutableSet(Set): + """A mutable set is a finite, iterable container. + + This class provides concrete generic implementations of all + methods except for __contains__, __iter__, __len__, + add(), and discard(). + + To override the comparisons (presumably for speed, as the + semantics are fixed), all you have to do is redefine __le__ and + then the other operations will automatically follow suit. + """ + + __slots__ = () + + @abstractmethod + def add(self, value): + """Add an element.""" + raise NotImplementedError + + @abstractmethod + def discard(self, value): + """Remove an element. Do not raise an exception if absent.""" + raise NotImplementedError + + def remove(self, value): + """Remove an element. If not a member, raise a KeyError.""" + if value not in self: + raise KeyError(value) + self.discard(value) + + def pop(self): + """Return the popped value. Raise KeyError if empty.""" + it = iter(self) + try: + value = next(it) + except StopIteration: + raise KeyError + self.discard(value) + return value + + def clear(self): + """This is slow (creates N new iterators!) but effective.""" + try: + while True: + self.pop() + except KeyError: + pass + + def __ior__(self, it): + for value in it: + self.add(value) + return self + + def __iand__(self, it): + for value in (self - it): + self.discard(value) + return self + + def __ixor__(self, it): + if it is self: + self.clear() + else: + if not isinstance(it, Set): + it = self._from_iterable(it) + for value in it: + if value in self: + self.discard(value) + else: + self.add(value) + return self + + def __isub__(self, it): + if it is self: + self.clear() + else: + for value in it: + self.discard(value) + return self + +MutableSet.register(set) + + +### MAPPINGS ### + + +class Mapping(Sized, Iterable, Container): + + __slots__ = () + + """A Mapping is a generic container for associating key/value + pairs. + + This class provides concrete generic implementations of all + methods except for __getitem__, __iter__, and __len__. + + """ + + @abstractmethod + def __getitem__(self, key): + raise KeyError + + def get(self, key, default=None): + 'D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.' + try: + return self[key] + except KeyError: + return default + + def __contains__(self, key): + try: + self[key] + except KeyError: + return False + else: + return True + + def keys(self): + "D.keys() -> a set-like object providing a view on D's keys" + return KeysView(self) + + def items(self): + "D.items() -> a set-like object providing a view on D's items" + return ItemsView(self) + + def values(self): + "D.values() -> an object providing a view on D's values" + return ValuesView(self) + + def __eq__(self, other): + if not isinstance(other, Mapping): + return NotImplemented + return dict(self.items()) == dict(other.items()) + + def __ne__(self, other): + return not (self == other) + +Mapping.register(mappingproxy) + + +class MappingView(Sized): + + def __init__(self, mapping): + self._mapping = mapping + + def __len__(self): + return len(self._mapping) + + def __repr__(self): + return '{0.__class__.__name__}({0._mapping!r})'.format(self) + + +class KeysView(MappingView, Set): + + @classmethod + def _from_iterable(self, it): + return set(it) + + def __contains__(self, key): + return key in self._mapping + + def __iter__(self): + yield from self._mapping + +KeysView.register(dict_keys) + + +class ItemsView(MappingView, Set): + + @classmethod + def _from_iterable(self, it): + return set(it) + + def __contains__(self, item): + key, value = item + try: + v = self._mapping[key] + except KeyError: + return False + else: + return v == value + + def __iter__(self): + for key in self._mapping: + yield (key, self._mapping[key]) + +ItemsView.register(dict_items) + + +class ValuesView(MappingView): + + def __contains__(self, value): + for key in self._mapping: + if value == self._mapping[key]: + return True + return False + + def __iter__(self): + for key in self._mapping: + yield self._mapping[key] + +ValuesView.register(dict_values) + + +class MutableMapping(Mapping): + + __slots__ = () + + """A MutableMapping is a generic container for associating + key/value pairs. + + This class provides concrete generic implementations of all + methods except for __getitem__, __setitem__, __delitem__, + __iter__, and __len__. + + """ + + @abstractmethod + def __setitem__(self, key, value): + raise KeyError + + @abstractmethod + def __delitem__(self, key): + raise KeyError + + __marker = object() + + def pop(self, key, default=__marker): + '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + ''' + try: + value = self[key] + except KeyError: + if default is self.__marker: + raise + return default + else: + del self[key] + return value + + def popitem(self): + '''D.popitem() -> (k, v), remove and return some (key, value) pair + as a 2-tuple; but raise KeyError if D is empty. + ''' + try: + key = next(iter(self)) + except StopIteration: + raise KeyError + value = self[key] + del self[key] + return key, value + + def clear(self): + 'D.clear() -> None. Remove all items from D.' + try: + while True: + self.popitem() + except KeyError: + pass + + def update(*args, **kwds): + ''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F. + If E present and has a .keys() method, does: for k in E: D[k] = E[k] + If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v + In either case, this is followed by: for k, v in F.items(): D[k] = v + ''' + if len(args) > 2: + raise TypeError("update() takes at most 2 positional " + "arguments ({} given)".format(len(args))) + elif not args: + raise TypeError("update() takes at least 1 argument (0 given)") + self = args[0] + other = args[1] if len(args) >= 2 else () + + if isinstance(other, Mapping): + for key in other: + self[key] = other[key] + elif hasattr(other, "keys"): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + def setdefault(self, key, default=None): + 'D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D' + try: + return self[key] + except KeyError: + self[key] = default + return default + +MutableMapping.register(dict) + + +### SEQUENCES ### + + +class Sequence(Sized, Iterable, Container): + + """All the operations on a read-only sequence. + + Concrete subclasses must override __new__ or __init__, + __getitem__, and __len__. + """ + + __slots__ = () + + @abstractmethod + def __getitem__(self, index): + raise IndexError + + def __iter__(self): + i = 0 + try: + while True: + v = self[i] + yield v + i += 1 + except IndexError: + return + + def __contains__(self, value): + for v in self: + if v == value: + return True + return False + + def __reversed__(self): + for i in reversed(range(len(self))): + yield self[i] + + def index(self, value): + '''S.index(value) -> integer -- return first index of value. + Raises ValueError if the value is not present. + ''' + for i, v in enumerate(self): + if v == value: + return i + raise ValueError + + def count(self, value): + 'S.count(value) -> integer -- return number of occurrences of value' + return sum(1 for v in self if v == value) + +Sequence.register(tuple) +Sequence.register(str) +Sequence.register(range) +Sequence.register(memoryview) + + +class ByteString(Sequence): + + """This unifies bytes and bytearray. + + XXX Should add all their methods. + """ + + __slots__ = () + +ByteString.register(bytes) +ByteString.register(bytearray) + + +class MutableSequence(Sequence): + + __slots__ = () + + """All the operations on a read-write sequence. + + Concrete subclasses must provide __new__ or __init__, + __getitem__, __setitem__, __delitem__, __len__, and insert(). + + """ + + @abstractmethod + def __setitem__(self, index, value): + raise IndexError + + @abstractmethod + def __delitem__(self, index): + raise IndexError + + @abstractmethod + def insert(self, index, value): + 'S.insert(index, value) -- insert value before index' + raise IndexError + + def append(self, value): + 'S.append(value) -- append value to the end of the sequence' + self.insert(len(self), value) + + def clear(self): + 'S.clear() -> None -- remove all items from S' + try: + while True: + self.pop() + except IndexError: + pass + + def reverse(self): + 'S.reverse() -- reverse *IN PLACE*' + n = len(self) + for i in range(n//2): + self[i], self[n-i-1] = self[n-i-1], self[i] + + def extend(self, values): + 'S.extend(iterable) -- extend sequence by appending elements from the iterable' + for v in values: + self.append(v) + + def pop(self, index=-1): + '''S.pop([index]) -> item -- remove and return item at index (default last). + Raise IndexError if list is empty or index is out of range. + ''' + v = self[index] + del self[index] + return v + + def remove(self, value): + '''S.remove(value) -- remove first occurrence of value. + Raise ValueError if the value is not present. + ''' + del self[self.index(value)] + + def __iadd__(self, values): + self.extend(values) + return self + +MutableSequence.register(list) +MutableSequence.register(bytearray) # Multiply inheriting, see ByteString diff --git a/python/testData/inspections/PyTypeCheckerInspection/TypingIterableForLoop.py b/python/testData/inspections/PyTypeCheckerInspection/TypingIterableForLoop.py new file mode 100644 index 000000000000..a734dd734635 --- /dev/null +++ b/python/testData/inspections/PyTypeCheckerInspection/TypingIterableForLoop.py @@ -0,0 +1,44 @@ +from typing import Iterable, Iterator, Sequence, List, Mapping, Dict + + +def f1() -> Iterable[int]: + pass + + +def f2() -> Iterator[int]: + pass + + +def f3() -> Sequence[int]: + pass + + +def f4() -> List[int]: + pass + + +def f5() -> Mapping[str, int]: + pass + + +def f6() -> Dict[str, int]: + pass + + +for x in f1(): + pass + +for x in f2(): + pass + +for x in f3(): + pass + +for x in f4(): + pass + +for x in f5(): + pass + +for x in f6(): + pass diff --git a/python/testData/inspections/PyTypeCheckerInspection/TypingListSubscriptionExpression.py b/python/testData/inspections/PyTypeCheckerInspection/TypingListSubscriptionExpression.py new file mode 100644 index 000000000000..242a41d363c6 --- /dev/null +++ b/python/testData/inspections/PyTypeCheckerInspection/TypingListSubscriptionExpression.py @@ -0,0 +1,7 @@ +from typing import List, Any + + +def f(x1: List[str], + x2: List['str'], + x3: List[Any]) -> None: + pass diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/unresolvedSubscriptionOnClass.py b/python/testData/inspections/PyUnresolvedReferencesInspection/unresolvedSubscriptionOnClass.py new file mode 100644 index 000000000000..773679e3afdd --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection/unresolvedSubscriptionOnClass.py @@ -0,0 +1,5 @@ +class Foo(object): + def __getitem__(self, item): + return item + +Foo[0] diff --git a/python/testData/typing/typing.py b/python/testData/typing/typing.py index fb82d6c56c30..ddaec3e72547 100644 --- a/python/testData/typing/typing.py +++ b/python/testData/typing/typing.py @@ -1,7 +1,5 @@ # TODO: -# - Tuple[..., t] -# - @no_type_check as class decorator -# - https://github.com/ambv/typehinting/issues/62 +# - Generic[T, T] is invalid # - Look for TODO below # TODO nits: @@ -12,7 +10,6 @@ import abc from abc import abstractmethod, abstractproperty import collections import functools -import inspect import re as stdlib_re # Avoid confusion with the re we export. import sys import types @@ -63,16 +60,10 @@ __all__ = [ 'List', 'Set', 'NamedTuple', # Not really a type. - - # Compile-time constants. - 'POSIX', - 'PY2', - 'PY3', - 'WINDOWS', + 'Generator', # One-off things. 'AnyStr', - 'Undefined', 'cast', 'get_type_hints', 'no_type_check', @@ -85,13 +76,6 @@ __all__ = [ ] -# Simple constants defined in the PEP. -PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] >= 3 -WINDOWS = sys.platform == 'win32' -POSIX = not WINDOWS - - def _qualname(x): if sys.version_info[:2] >= (3, 3): return x.__qualname__ @@ -144,6 +128,8 @@ class TypingMeta(type): class Final: """Mix-in class to prevent instantiation.""" + __slots__ = () + def __new__(self, *args, **kwds): raise TypeError("Cannot instantiate %r" % self.__class__) @@ -164,6 +150,12 @@ class _ForwardRef(TypingMeta): self.__forward_code__ = code self.__forward_evaluated__ = False self.__forward_value__ = None + typing_globals = globals() + frame = sys._getframe(1) + while frame is not None and frame.f_globals is typing_globals: + frame = frame.f_back + assert frame is not None + self.__forward_frame__ = frame return self def _eval_type(self, globalns, localns): @@ -174,11 +166,31 @@ class _ForwardRef(TypingMeta): raise TypeError('ForwardRef globalns must be a dict -- got %r' % (globalns,)) if not self.__forward_evaluated__: - self.__forward_value__ = eval(self.__forward_code__, - globalns, localns) + if globalns is None and localns is None: + globalns = localns = {} + elif globalns is None: + globalns = localns + elif localns is None: + localns = globalns + self.__forward_value__ = _type_check( + eval(self.__forward_code__, globalns, localns), + "Forward references must evaluate to types.") self.__forward_evaluated__ = True return self.__forward_value__ + def __instancecheck__(self, obj): + raise TypeError("Forward references cannot be used with isinstance().") + + def __subclasscheck__(self, cls): + if not self.__forward_evaluated__: + globalns = self.__forward_frame__.f_globals + localns = self.__forward_frame__.f_locals + try: + self._eval_type(globalns, localns) + except NameError: + return False # Too early. + return issubclass(cls, self.__forward_value__) + def __repr__(self): return '_ForwardRef(%r)' % (self.__forward_arg__,) @@ -194,6 +206,8 @@ class _TypeAlias: False. """ + __slots__ = ('name', 'type_var', 'impl_type', 'type_checker') + def __new__(cls, *args, **kwds): """Constructor. @@ -234,15 +248,15 @@ class _TypeAlias: assert isinstance(parameter, type), repr(parameter) if not isinstance(self.type_var, TypeVar): raise TypeError("%s cannot be further parameterized." % self) - if not issubclass(parameter, self.type_var): - raise TypeError("%s is not a valid substitution for %s." % - (parameter, self.type_var)) + if self.type_var.__constraints__: + if not issubclass(parameter, Union[self.type_var.__constraints__]): + raise TypeError("%s is not a valid substitution for %s." % + (parameter, self.type_var)) return self.__class__(self.name, parameter, self.impl_type, self.type_checker) def __instancecheck__(self, obj): - return (isinstance(obj, self.impl_type) and - isinstance(self.type_checker(obj), self.type_var)) + raise TypeError("Type aliases cannot be used with isinstance().") def __subclasscheck__(self, cls): if cls is Any: @@ -314,8 +328,8 @@ class AnyMeta(TypingMeta): self = super().__new__(cls, name, bases, namespace, _root=_root) return self - def __instancecheck__(self, instance): - return True + def __instancecheck__(self, obj): + raise TypeError("Any cannot be used with isinstance().") def __subclasscheck__(self, cls): if not isinstance(cls, type): @@ -331,177 +345,108 @@ class Any(Final, metaclass=AnyMeta, _root=True): - As a special case, Any and object are subclasses of each other. """ + __slots__ = () + class TypeVar(TypingMeta, metaclass=TypingMeta, _root=True): """Type variable. Usage:: - T1 = TypeVar('T1') # Unconstrained - T2 = TypeVar('T2', t1, t2, ...) # Constrained to any of (t1, t2, ...) + T = TypeVar('T') # Can be anything + A = TypeVar('A', str, bytes) # Must be str or bytes - For an unconstrained type variable T, isinstance(x, T) is false - for all x, and similar for issubclass(cls, T). Example:: + Type variables exist primarily for the benefit of static type + checkers. They serve as the parameters for generic types as well + as for generic function definitions. See class Generic for more + information on generic types. Generic functions work as follows: - T = TypeVar('T') - assert not isinstance(42, T) - assert not issubclass(int, T) + def repeat(x: T, n: int) -> Sequence[T]: + '''Return a list containing n references to x.''' + return [x]*n - For a constrained type variable T, isinstance(x, T) is true for - any x that is an instance of at least one of T's constraints, - and similar for issubclass(cls, T). Example:: + def longest(x: A, y: A) -> A: + '''Return the longest of two strings.''' + return x if len(x) >= len(y) else y - AnyStr = TypeVar('AnyStr', str, bytes) - # AnyStr behaves similar to Union[str, bytes] (but not exactly!) - assert not isinstance(42, AnyStr) - assert isinstance('', AnyStr) - assert isinstance(b'', AnyStr) - assert not issubclass(int, AnyStr) - assert issubclass(str, AnyStr) - assert issubclass(bytes, AnyStr) + The latter example's signature is essentially the overloading + of (str, str) -> str and (bytes, bytes) -> bytes. Also note + that if the arguments are instances of some subclass of str, + the return type is still plain str. - Type variables that are distinct objects are never equal (even if - created with the same parameters). + At runtime, isinstance(x, T) will raise TypeError. However, + issubclass(C, T) is true for any class C, and issubclass(str, A) + and issubclass(bytes, A) are true, and issubclass(int, A) is + false. - You can temporarily *bind* a type variable to a specific type by - calling its bind() method and using the result as a context - manager (i.e., in a with-statement). Example:: + Type variables may be marked covariant or contravariant by passing + covariant=True or contravariant=True. See PEP 484 for more + details. By default type variables are invariant. - with T.bind(int): - # In this block, T is nearly an alias for int. - assert isinstance(42, T) - assert issubclass(int, T) - - There is still a difference between T and int; issubclass(T, int) - is False. However, issubclass(int, T) is true. - - Binding a constrained type variable will replace the binding type - with the most derived of its constraints that matches. Example:: - - class MyStr(str): - pass - - with AnyStr.bind(MyStr): - # In this block, AnyStr is an alias for str, not for MyStr. - assert isinstance('', AnyStr) - assert issubclass(str, AnyStr) - assert not isinstance(b'', AnyStr) - assert not issubclass(bytes, AnyStr) + Type variables can be introspected. e.g.: + T.__name__ == 'T' + T.__constraints__ == () + T.__covariant__ == False + T.__contravariant__ = False + A.__constraints__ == (str, bytes) """ - def __new__(cls, name, *constraints): + def __new__(cls, name, *constraints, bound=None, + covariant=False, contravariant=False): self = super().__new__(cls, name, (Final,), {}, _root=True) + if covariant and contravariant: + raise ValueError("Bivariant type variables are not supported.") + self.__covariant__ = bool(covariant) + self.__contravariant__ = bool(contravariant) + if constraints and bound is not None: + raise TypeError("Constraints cannot be combined with bound=...") + if constraints and len(constraints) == 1: + raise TypeError("A single constraint is not allowed") msg = "TypeVar(name, constraint, ...): constraints must be types." self.__constraints__ = tuple(_type_check(t, msg) for t in constraints) - self.__binding__ = None + if bound: + self.__bound__ = _type_check(bound, "Bound must be a type.") + else: + self.__bound__ = None return self def _has_type_var(self): return True def __repr__(self): - return '~' + self.__name__ + if self.__covariant__: + prefix = '+' + elif self.__contravariant__: + prefix = '-' + else: + prefix = '~' + return prefix + self.__name__ def __instancecheck__(self, instance): - if self.__binding__ is not None: - return isinstance(instance, self.__binding__) - elif not self.__constraints__: - return False - else: - return isinstance(instance, Union[self.__constraints__]) + raise TypeError("Type variables cannot be used with isinstance().") def __subclasscheck__(self, cls): - if cls is Any: - return True + # TODO: Make this raise TypeError too? if cls is self: return True - elif self.__binding__ is not None: - return issubclass(cls, self.__binding__) - elif not self.__constraints__: - return False - else: - return issubclass(cls, Union[self.__constraints__]) - - def bind(self, binding): - binding = _type_check(binding, "TypeVar.bind(t): t must be a type.") + if cls is Any: + return True + if self.__bound__ is not None: + return issubclass(cls, self.__bound__) if self.__constraints__: - best = None - for t in self.__constraints__: - if (issubclass(binding, t) and - (best is None or issubclass(t, best))): - best = t - if best is None: - raise TypeError( - "TypeVar.bind(t): t must match one of the constraints.") - binding = best - return VarBinding(self, binding) - - def _bind(self, binding): - old_binding = self.__binding__ - self.__binding__ = binding - return old_binding - - def _unbind(self, binding, old_binding): - assert self.__binding__ is binding, (self.__binding__, - binding, old_binding) - self.__binding__ = old_binding - - -# Compatibility for for mypy's typevar(). -def typevar(name, values=()): - return TypeVar(name, *values) - - -class VarBinding: - """TypeVariable binding returned by TypeVar.bind().""" - - # TODO: This is not thread-safe. We could solve this in one of - # two ways: by using a lock or by using thread-local state. But - # either of these feels overly heavy, and still doesn't work - # e.g. in an asyncio Task. - - def __init__(self, var, binding): - assert isinstance(var, TypeVar), (var, binding) - assert isinstance(binding, type), (var, binding) - self._var = var - self._binding = binding - self._old_binding = None - self._entered = False - - def __enter__(self): - if self._entered: - # This checks for the following scenario: - # bv = T.bind() - # with bv: - # with bv: # Will raise here. - # ... - # However, the following scenario is OK (if somewhat odd): - # bv = T.bind() - # with bv: - # ... - # with bv: - # ... - # The following scenario is also fine: - # with T.bind(): - # with T.bind(): - # ... - raise TypeError("Cannot reuse variable binding recursively.") - self._old_binding = self._var._bind(self._binding) - self._entered = True - - def __exit__(self, *args): - try: - self._var._unbind(self._binding, self._old_binding) - finally: - self._entered = False - self._old_binding = None + return any(issubclass(cls, c) for c in self.__constraints__) + return True # Some unconstrained type variables. These are used by the container types. T = TypeVar('T') # Any type. KT = TypeVar('KT') # Key type. VT = TypeVar('VT') # Value type. +T_co = TypeVar('T_co', covariant=True) # Any type covariant containers. +V_co = TypeVar('V_co', covariant=True) # Any type covariant containers. +VT_co = TypeVar('VT_co', covariant=True) # Value type covariant containers. +T_contra = TypeVar('T_contra', contravariant=True) # Ditto contravariant. # A useful type variable with constraints. This represents string types. # TODO: What about bytearray, memoryview? @@ -538,11 +483,16 @@ class UnionMeta(TypingMeta): # E.g. Union[int, Employee, Manager] == Union[int, Employee]. # If Any or object is present it will be the sole survivor. # If both Any and object are present, Any wins. + # Never discard type variables, except against Any. + # (In particular, Union[str, AnyStr] != AnyStr.) all_params = set(params) for t1 in params: if t1 is Any: return Any - if any(issubclass(t1, t2) for t2 in all_params - {t1}): + if isinstance(t1, TypeVar): + continue + if any(issubclass(t1, t2) + for t2 in all_params - {t1} if not isinstance(t2, TypeVar)): all_params.remove(t1) # It's not a union if there's only one type left. if len(all_params) == 1: @@ -595,9 +545,8 @@ class UnionMeta(TypingMeta): def __hash__(self): return hash(self.__union_set_params__) - def __instancecheck__(self, instance): - return (self.__union_set_params__ is not None and - any(isinstance(instance, t) for t in self.__union_params__)) + def __instancecheck__(self, obj): + raise TypeError("Unions cannot be used with isinstance().") def __subclasscheck__(self, cls): if cls is Any: @@ -692,13 +641,17 @@ class Optional(Final, metaclass=OptionalMeta, _root=True): Optional[X] is equivalent to Union[X, type(None)]. """ + __slots__ = () + class TupleMeta(TypingMeta): """Metaclass for Tuple.""" - def __new__(cls, name, bases, namespace, parameters=None, _root=False): + def __new__(cls, name, bases, namespace, parameters=None, + use_ellipsis=False, _root=False): self = super().__new__(cls, name, bases, namespace, _root=_root) self.__tuple_params__ = parameters + self.__tuple_use_ellipsis__ = use_ellipsis return self def _has_type_var(self): @@ -722,8 +675,11 @@ class TupleMeta(TypingMeta): def __repr__(self): r = super().__repr__() if self.__tuple_params__ is not None: + params = [_type_repr(p) for p in self.__tuple_params__] + if self.__tuple_use_ellipsis__: + params.append('...') r += '[%s]' % ( - ', '.join(_type_repr(p) for p in self.__tuple_params__)) + ', '.join(params)) return r def __getitem__(self, parameters): @@ -731,10 +687,17 @@ class TupleMeta(TypingMeta): raise TypeError("Cannot re-parameterize %r" % (self,)) if not isinstance(parameters, tuple): parameters = (parameters,) - msg = "Class[arg, ...]: each arg must be a type." + if len(parameters) == 2 and parameters[1] == Ellipsis: + parameters = parameters[:1] + use_ellipsis = True + msg = "Tuple[t, ...]: t must be a type." + else: + use_ellipsis = False + msg = "Tuple[t0, t1, ...]: each t must be a type." parameters = tuple(_type_check(p, msg) for p in parameters) return self.__class__(self.__name__, self.__bases__, - dict(self.__dict__), parameters, _root=True) + dict(self.__dict__), parameters, + use_ellipsis=use_ellipsis, _root=True) def __eq__(self, other): if not isinstance(other, TupleMeta): @@ -744,14 +707,8 @@ class TupleMeta(TypingMeta): def __hash__(self): return hash(self.__tuple_params__) - def __instancecheck__(self, t): - if not isinstance(t, tuple): - return False - if self.__tuple_params__ is None: - return True - return (len(t) == len(self.__tuple_params__) and - all(isinstance(x, p) - for x, p in zip(t, self.__tuple_params__))) + def __instancecheck__(self, obj): + raise TypeError("Tuples cannot be used with isinstance().") def __subclasscheck__(self, cls): if cls is Any: @@ -766,6 +723,8 @@ class TupleMeta(TypingMeta): return True if cls.__tuple_params__ is None: return False # ??? + if cls.__tuple_use_ellipsis__ != self.__tuple_use_ellipsis__: + return False # Covariance. return (len(self.__tuple_params__) == len(cls.__tuple_params__) and all(issubclass(x, p) @@ -783,6 +742,8 @@ class Tuple(Final, metaclass=TupleMeta, _root=True): To specify a variable-length tuple of homogeneous type, use Sequence[T]. """ + __slots__ = () + class CallableMeta(TypingMeta): """Metaclass for Callable.""" @@ -816,7 +777,10 @@ class CallableMeta(TypingMeta): def _eval_type(self, globalns, localns): if self.__args__ is None and self.__result__ is None: return self - args = [_eval_type(t, globalns, localns) for t in self.__args__] + if self.__args__ is Ellipsis: + args = self.__args__ + else: + args = [_eval_type(t, globalns, localns) for t in self.__args__] result = _eval_type(self.__result__, globalns, localns) if args == self.__args__ and result == self.__result__: return self @@ -827,10 +791,12 @@ class CallableMeta(TypingMeta): def __repr__(self): r = super().__repr__() if self.__args__ is not None or self.__result__ is not None: - r += '%s[[%s], %s]' % (_qualname(self), - ', '.join(_type_repr(t) - for t in self.__args__), - _type_repr(self.__result__)) + if self.__args__ is Ellipsis: + args_r = '...' + else: + args_r = '[%s]' % ', '.join(_type_repr(t) + for t in self.__args__) + r += '[%s, %s]' % (args_r, _type_repr(self.__result__)) return r def __getitem__(self, parameters): @@ -853,56 +819,14 @@ class CallableMeta(TypingMeta): def __hash__(self): return hash(self.__args__) ^ hash(self.__result__) - def __instancecheck__(self, instance): - if not callable(instance): - return False + def __instancecheck__(self, obj): + # For unparametrized Callable we allow this, because + # typing.Callable should be equivalent to + # collections.abc.Callable. if self.__args__ is None and self.__result__ is None: - return True - assert self.__args__ is not None - assert self.__result__ is not None - my_args, my_result = self.__args__, self.__result__ - # Would it be better to use Signature objects? - try: - (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, - annotations) = inspect.getfullargspec(instance) - except TypeError: - return False # We can't find the signature. Give up. - msg = ("When testing isinstance(, Callable[...], " - "'s annotations must be types.") - if my_args is not Ellipsis: - if kwonlyargs and (not kwonlydefaults or - len(kwonlydefaults) < len(kwonlyargs)): - return False - if isinstance(instance, types.MethodType): - # For methods, getfullargspec() includes self/cls, - # but it's not part of the call signature, so drop it. - del args[0] - min_call_args = len(args) - if defaults: - min_call_args -= len(defaults) - if varargs: - max_call_args = 999999999 - if len(args) < len(my_args): - args += [varargs] * (len(my_args) - len(args)) - else: - max_call_args = len(args) - if not min_call_args <= len(my_args) <= max_call_args: - return False - for my_arg_type, name in zip(my_args, args): - if name in annotations: - annot_type = _type_check(annotations[name], msg) - else: - annot_type = Any - if not issubclass(my_arg_type, annot_type): - return False - # TODO: If mutable type, check invariance? - if 'return' in annotations: - annot_return_type = _type_check(annotations['return'], msg) - # Note contravariance here! - if not issubclass(annot_return_type, my_result): - return False - # Can't find anything wrong... - return True + return isinstance(obj, collections_abc.Callable) + else: + raise TypeError("Callable[] cannot be used with isinstance().") def __subclasscheck__(self, cls): if cls is Any: @@ -926,6 +850,31 @@ class Callable(Final, metaclass=CallableMeta, _root=True): such function types are rarely used as callback types. """ + __slots__ = () + + +def _gorg(a): + """Return the farthest origin of a generic class.""" + assert isinstance(a, GenericMeta) + while a.__origin__ is not None: + a = a.__origin__ + return a + + +def _geqv(a, b): + """Return whether two generic classes are equivalent. + + The intention is to consider generic class X and any of its + parameterized forms (X[T], X[int], etc.) as equivalent. + + However, X is not equivalent to a subclass of X. + + The relation is reflexive, symmetric and transitive. + """ + assert isinstance(a, GenericMeta) and isinstance(b, GenericMeta) + # Reduce each to its origin. + return _gorg(a) is _gorg(b) + class GenericMeta(TypingMeta, abc.ABCMeta): """Metaclass for generic types.""" @@ -933,9 +882,15 @@ class GenericMeta(TypingMeta, abc.ABCMeta): # TODO: Constrain more how Generic is used; only a few # standard patterns should be allowed. + # TODO: Use a more precise rule than matching __name__ to decide + # whether two classes are the same. Also, save the formal + # parameters. (These things are related! A solution lies in + # using origin.) + __extra__ = None - def __new__(cls, name, bases, namespace, parameters=None, extra=None): + def __new__(cls, name, bases, namespace, + parameters=None, origin=None, extra=None): if parameters is None: # Extract parameters from direct base classes. Only # direct bases are considered and only those that are @@ -969,6 +924,7 @@ class GenericMeta(TypingMeta, abc.ABCMeta): self.__extra__ = extra # Else __extra__ is inherited, eventually from the # (meta-)class default above. + self.__origin__ = origin return self def _has_type_var(self): @@ -988,7 +944,7 @@ class GenericMeta(TypingMeta, abc.ABCMeta): def __eq__(self, other): if not isinstance(other, GenericMeta): return NotImplemented - return (self.__name__ == other.__name__ and + return (_geqv(self, other) and self.__parameters__ == other.__parameters__) def __hash__(self): @@ -1006,14 +962,20 @@ class GenericMeta(TypingMeta, abc.ABCMeta): if not isinstance(p, TypeVar): raise TypeError("Initial parameters must be " "type variables; got %s" % p) + if len(set(params)) != len(params): + raise TypeError("All type variables in Generic[...] must be distinct.") else: if len(params) != len(self.__parameters__): raise TypeError("Cannot change parameter count from %d to %d" % (len(self.__parameters__), len(params))) for new, old in zip(params, self.__parameters__): - if isinstance(old, TypeVar) and not old.__constraints__: - # Substituting for an unconstrained TypeVar is always OK. - continue + if isinstance(old, TypeVar): + if not old.__constraints__: + # Substituting for an unconstrained TypeVar is OK. + continue + if issubclass(new, Union[old.__constraints__]): + # Specializing a constrained type variable is OK. + continue if not issubclass(new, old): raise TypeError( "Cannot substitute %s for %s in %s" % @@ -1021,24 +983,50 @@ class GenericMeta(TypingMeta, abc.ABCMeta): return self.__class__(self.__name__, self.__bases__, dict(self.__dict__), - parameters=params, extra=self.__extra__) + parameters=params, + origin=self, + extra=self.__extra__) def __subclasscheck__(self, cls): if cls is Any: return True + if isinstance(cls, GenericMeta): + # For a class C(Generic[T]) where T is co-variant, + # C[X] is a subclass of C[Y] iff X is a subclass of Y. + origin = self.__origin__ + if origin is not None and origin is cls.__origin__: + assert len(self.__parameters__) == len(origin.__parameters__) + assert len(cls.__parameters__) == len(origin.__parameters__) + for p_self, p_cls, p_origin in zip(self.__parameters__, + cls.__parameters__, + origin.__parameters__): + if isinstance(p_origin, TypeVar): + if p_origin.__covariant__: + # Covariant -- p_cls must be a subclass of p_self. + if not issubclass(p_cls, p_self): + break + elif p_origin.__contravariant__: + # Contravariant. I think it's the opposite. :-) + if not issubclass(p_self, p_cls): + break + else: + # Invariant -- p_cls and p_self must equal. + if p_self != p_cls: + break + else: + # If the origin's parameter is not a typevar, + # insist on invariance. + if p_self != p_cls: + break + else: + return True + # If we break out of the loop, the superclass gets a chance. if super().__subclasscheck__(cls): return True - if self.__extra__ is None: + if self.__extra__ is None or isinstance(cls, GenericMeta): return False return issubclass(cls, self.__extra__) - def __instancecheck__(self, obj): - if super().__instancecheck__(obj): - return True - if self.__extra__ is None: - return False - return isinstance(obj, self.__extra__) - class Generic(metaclass=GenericMeta): """Abstract base class for generic types. @@ -1068,47 +1056,15 @@ class Generic(metaclass=GenericMeta): # Same body as above. """ + __slots__ = () -class Undefined: - """An undefined value. - - Example:: - - x = Undefined(typ) - - This tells the type checker that x has the given type but its - value should be considered undefined. At runtime x is an instance - of Undefined. The actual type can be introspected by looking at - x.__type__ and its str() and repr() are defined, but any other - operations or attributes will raise an exception. - - An alternative syntax is also supported: - - x = Undefined # type: typ - - This has the same meaning to the static type checker but uses less - overhead at run-time, at the cost of not being introspectible. - - NOTE: Do not under any circumstances check for Undefined. We - don't want this to become something developers rely upon, like - JavaScript's undefined. Code that returns or uses an Undefined - value in any way should be considered broken. Static type - checkers should warn about using potentially Undefined values. - """ - - __slots__ = ['__type__'] - - def __new__(cls, typ): - typ = _type_check(typ, "Undefined(t): t must be a type.") - self = super().__new__(cls) - self.__type__ = typ - return self - - __hash__ = None - - def __repr__(self): - return '%s(%s)' % (_type_repr(self.__class__), - _type_repr(self.__type__)) + def __new__(cls, *args, **kwds): + next_in_mro = object + # Look for the last occurrence of Generic or Generic[...]. + for i, c in enumerate(cls.__mro__[:-1]): + if isinstance(c, GenericMeta) and _gorg(c) is Generic: + next_in_mro = cls.__mro__[i+1] + return next_in_mro.__new__(_gorg(cls)) def cast(typ, val): @@ -1151,8 +1107,9 @@ def get_type_hints(obj, globalns=None, localns=None): (unless you are familiar with how eval() and exec() work). The search order is locals first, then globals. - - If no dict arguments are passed, the defaults are taken from the - globals and locals of the caller, respectively. + - If no dict arguments are passed, an attempt is made to use the + globals from obj, and these are also used as the locals. If the + object does not appear to have globals, an exception is raised. - If one dict argument is passed, it is used for both globals and locals. @@ -1163,9 +1120,9 @@ def get_type_hints(obj, globalns=None, localns=None): if getattr(obj, '__no_type_check__', None): return {} if globalns is None: - globalns = sys._getframe(1).f_globals + globalns = getattr(obj, '__globals__', {}) if localns is None: - localns = sys._getframe(1).f_locals + localns = globalns elif localns is None: localns = globalns defaults = _get_defaults(obj) @@ -1181,13 +1138,22 @@ def get_type_hints(obj, globalns=None, localns=None): # TODO: Also support this as a class decorator. -def no_type_check(func): +def no_type_check(arg): """Decorator to indicate that annotations are not type hints. - This mutates the function in place. + The argument must be a class or function; if it is a class, it + applies recursively to all methods defined in that class (but not + to methods defined in its superclasses or subclasses). + + This mutates the function(s) in place. """ - func.__no_type_check__ = True - return func + if isinstance(arg, type): + for obj in arg.__dict__.values(): + if isinstance(obj, types.FunctionType): + obj.__no_type_check__ = True + else: + arg.__no_type_check__ = True + return arg def no_type_check_decorator(decorator): @@ -1210,18 +1176,17 @@ def overload(func): raise RuntimeError("Overloading is only supported in library stubs") -class _Protocol(Generic): - """Internal base class for protocol classes. +class _ProtocolMeta(GenericMeta): + """Internal metaclass for _Protocol. - This implements a simple-minded structural isinstance check - (similar but more general than the one-offs in collections.abc - such as Hashable). + This exists so _Protocol classes can be generic without deriving + from Generic. """ - _is_protocol = True + def __instancecheck__(self, obj): + raise TypeError("Protocols cannot be used with isinstance().") - @classmethod - def __subclasshook__(self, cls): + def __subclasscheck__(self, cls): if not self._is_protocol: # No structural checks since this isn't a protocol. return NotImplemented @@ -1235,10 +1200,9 @@ class _Protocol(Generic): for attr in attrs: if not any(attr in d.__dict__ for d in cls.__mro__): - return NotImplemented + return False return True - @classmethod def _get_protocol_attrs(self): # Get all Protocol base classes. protocol_bases = [] @@ -1260,28 +1224,45 @@ class _Protocol(Generic): attr != '__abstractmethods__' and attr != '_is_protocol' and attr != '__dict__' and + attr != '__slots__' and attr != '_get_protocol_attrs' and + attr != '__parameters__' and + attr != '__origin__' and attr != '__module__'): attrs.add(attr) return attrs +class _Protocol(metaclass=_ProtocolMeta): + """Internal base class for protocol classes. + + This implements a simple-minded structural isinstance check + (similar but more general than the one-offs in collections.abc + such as Hashable). + """ + + __slots__ = () + + _is_protocol = True + + # Various ABCs mimicking those in collections.abc. # A few are simply re-exported for completeness. Hashable = collections_abc.Hashable # Not generic. -class Iterable(Generic[T], extra=collections_abc.Iterable): - pass +class Iterable(Generic[T_co], extra=collections_abc.Iterable): + __slots__ = () -class Iterator(Iterable, extra=collections_abc.Iterator): - pass +class Iterator(Iterable[T_co], extra=collections_abc.Iterator): + __slots__ = () class SupportsInt(_Protocol): + __slots__ = () @abstractmethod def __int__(self) -> int: @@ -1289,65 +1270,88 @@ class SupportsInt(_Protocol): class SupportsFloat(_Protocol): + __slots__ = () @abstractmethod def __float__(self) -> float: pass -class SupportsAbs(_Protocol[T]): +class SupportsComplex(_Protocol): + __slots__ = () @abstractmethod - def __abs__(self) -> T: + def __complex__(self) -> complex: pass -class SupportsRound(_Protocol[T]): +class SupportsBytes(_Protocol): + __slots__ = () @abstractmethod - def __round__(self, ndigits: int = 0) -> T: + def __bytes__(self) -> bytes: pass -class Reversible(_Protocol[T]): +class SupportsAbs(_Protocol[T_co]): + __slots__ = () @abstractmethod - def __reversed__(self) -> 'Iterator[T]': + def __abs__(self) -> T_co: + pass + + +class SupportsRound(_Protocol[T_co]): + __slots__ = () + + @abstractmethod + def __round__(self, ndigits: int = 0) -> T_co: + pass + + +class Reversible(_Protocol[T_co]): + __slots__ = () + + @abstractmethod + def __reversed__(self) -> 'Iterator[T_co]': pass Sized = collections_abc.Sized # Not generic. -class Container(Generic[T], extra=collections_abc.Container): - pass +class Container(Generic[T_co], extra=collections_abc.Container): + __slots__ = () # Callable was defined earlier. -class AbstractSet(Sized, Iterable, Container, extra=collections_abc.Set): +class AbstractSet(Sized, Iterable[T_co], Container[T_co], + extra=collections_abc.Set): pass -class MutableSet(AbstractSet, extra=collections_abc.MutableSet): +class MutableSet(AbstractSet[T], extra=collections_abc.MutableSet): pass -class Mapping(Sized, Iterable[KT], Container[KT], Generic[KT, VT], +# NOTE: Only the value type is covariant. +class Mapping(Sized, Iterable[KT], Container[KT], Generic[VT_co], extra=collections_abc.Mapping): pass -class MutableMapping(Mapping, extra=collections_abc.MutableMapping): +class MutableMapping(Mapping[KT, VT], extra=collections_abc.MutableMapping): pass -class Sequence(Sized, Iterable, Container, extra=collections_abc.Sequence): +class Sequence(Sized, Iterable[T_co], Container[T_co], + extra=collections_abc.Sequence): pass -class MutableSequence(Sequence, extra=collections_abc.MutableSequence): +class MutableSequence(Sequence[T], extra=collections_abc.MutableSequence): pass @@ -1358,39 +1362,25 @@ class ByteString(Sequence[int], extra=collections_abc.ByteString): ByteString.register(type(memoryview(b''))) -class _ListMeta(GenericMeta): +class List(list, MutableSequence[T]): - def __instancecheck__(self, obj): - if not super().__instancecheck__(obj): - return False - itemtype = self.__parameters__[0] - for x in obj: - if not isinstance(x, itemtype): - return False - return True + def __new__(cls, *args, **kwds): + if _geqv(cls, List): + raise TypeError("Type List cannot be instantiated; " + "use list() instead") + return list.__new__(cls, *args, **kwds) -class List(list, MutableSequence, metaclass=_ListMeta): - pass +class Set(set, MutableSet[T]): + + def __new__(cls, *args, **kwds): + if _geqv(cls, Set): + raise TypeError("Type Set cannot be instantiated; " + "use set() instead") + return set.__new__(cls, *args, **kwds) -class _SetMeta(GenericMeta): - - def __instancecheck__(self, obj): - if not super().__instancecheck__(obj): - return False - itemtype = self.__parameters__[0] - for x in obj: - if not isinstance(x, itemtype): - return False - return True - - -class Set(set, MutableSet, metaclass=_SetMeta): - pass - - -class _FrozenSetMeta(_SetMeta): +class _FrozenSetMeta(GenericMeta): """This metaclass ensures set is not a subclass of FrozenSet. Without this metaclass, set would be considered a subclass of @@ -1403,48 +1393,63 @@ class _FrozenSetMeta(_SetMeta): return False return super().__subclasscheck__(cls) - def __instancecheck__(self, obj): - if issubclass(obj.__class__, Set): - return False - return super().__instancecheck__(obj) + +class FrozenSet(frozenset, AbstractSet[T_co], metaclass=_FrozenSetMeta): + __slots__ = () + + def __new__(cls, *args, **kwds): + if _geqv(cls, FrozenSet): + raise TypeError("Type FrozenSet cannot be instantiated; " + "use frozenset() instead") + return frozenset.__new__(cls, *args, **kwds) -class FrozenSet(frozenset, AbstractSet, metaclass=_FrozenSetMeta): +class MappingView(Sized, Iterable[T_co], extra=collections_abc.MappingView): pass -class MappingView(Sized, Iterable, extra=collections_abc.MappingView): +class KeysView(MappingView[KT], AbstractSet[KT], + extra=collections_abc.KeysView): pass -class KeysView(MappingView, Set[KT], extra=collections_abc.KeysView): +# TODO: Enable Set[Tuple[KT, VT_co]] instead of Generic[KT, VT_co]. +class ItemsView(MappingView, Generic[KT, VT_co], + extra=collections_abc.ItemsView): pass -# TODO: Enable Set[Tuple[KT, VT]] instead of Generic[KT, VT]. -class ItemsView(MappingView, Generic[KT, VT], extra=collections_abc.ItemsView): +class ValuesView(MappingView[VT_co], extra=collections_abc.ValuesView): pass -class ValuesView(MappingView, extra=collections_abc.ValuesView): - pass +class Dict(dict, MutableMapping[KT, VT]): + + def __new__(cls, *args, **kwds): + if _geqv(cls, Dict): + raise TypeError("Type Dict cannot be instantiated; " + "use dict() instead") + return dict.__new__(cls, *args, **kwds) -class _DictMeta(GenericMeta): - - def __instancecheck__(self, obj): - if not super().__instancecheck__(obj): - return False - keytype, valuetype = self.__parameters__ - for key, value in obj.items(): - if not (isinstance(key, keytype) and - isinstance(value, valuetype)): - return False - return True +# Determine what base class to use for Generator. +if hasattr(collections_abc, 'Generator'): + # Sufficiently recent versions of 3.5 have a Generator ABC. + _G_base = collections_abc.Generator +else: + # Fall back on the exact type. + _G_base = types.GeneratorType -class Dict(dict, MutableMapping, metaclass=_DictMeta): - pass +class Generator(Iterator[T_co], Generic[T_co, T_contra, V_co], + extra=_G_base): + __slots__ = () + + def __new__(cls, *args, **kwds): + if _geqv(cls, Generator): + raise TypeError("Type Generator cannot be instantiated; " + "create a subclass instead") + return super().__new__(cls, *args, **kwds) def NamedTuple(typename, fields): @@ -1482,6 +1487,8 @@ class IO(Generic[AnyStr]): way to track the other distinctions in the type system. """ + __slots__ = () + @abstractproperty def mode(self) -> str: pass @@ -1566,6 +1573,8 @@ class IO(Generic[AnyStr]): class BinaryIO(IO[bytes]): """Typed version of the return of open() in binary mode.""" + __slots__ = () + @abstractmethod def write(self, s: Union[bytes, bytearray]) -> int: pass @@ -1578,6 +1587,8 @@ class BinaryIO(IO[bytes]): class TextIO(IO[str]): """Typed version of the return of open() in text mode.""" + __slots__ = () + @abstractproperty def buffer(self) -> BinaryIO: pass diff --git a/python/testSrc/com/jetbrains/python/Py3TypeTest.java b/python/testSrc/com/jetbrains/python/Py3TypeTest.java index 44d84c9bfdc6..a53df7457cbc 100644 --- a/python/testSrc/com/jetbrains/python/Py3TypeTest.java +++ b/python/testSrc/com/jetbrains/python/Py3TypeTest.java @@ -114,7 +114,6 @@ public class Py3TypeTest extends PyTestCase { " expr = await foo()\n"); } }); - } private void doTest(final String expectedType, final String text) { diff --git a/python/testSrc/com/jetbrains/python/PyTypingTest.java b/python/testSrc/com/jetbrains/python/PyTypingTest.java index b6126e9abeb6..7409f24faeb3 100644 --- a/python/testSrc/com/jetbrains/python/PyTypingTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypingTest.java @@ -340,6 +340,18 @@ public class PyTypingTest extends PyTestCase { " pass\n"); } + // PY-16125 + public void testIterableForLoop() { + doTest("int", + "from typing import Iterable\n" + + "\n" + + "def foo() -> Iterable[int]:\n" + + " passs\n" + + "\n" + + "for expr in foo():\n" + + " pass\n"); + } + private void doTestNoInjectedText(@NotNull String text) { myFixture.configureByText(PythonFileType.INSTANCE, text); final InjectedLanguageManager languageManager = InjectedLanguageManager.getInstance(myFixture.getProject()); diff --git a/python/testSrc/com/jetbrains/python/inspections/Py3TypeCheckerInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/Py3TypeCheckerInspectionTest.java index ba55e201a4b5..b3fc9efa0b0e 100644 --- a/python/testSrc/com/jetbrains/python/inspections/Py3TypeCheckerInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/Py3TypeCheckerInspectionTest.java @@ -31,9 +31,10 @@ public class Py3TypeCheckerInspectionTest extends PyTestCase { } private void doTest() { - runWithLanguageLevel(LanguageLevel.PYTHON32, new Runnable() { + runWithLanguageLevel(LanguageLevel.PYTHON35, new Runnable() { @Override public void run() { + myFixture.copyDirectoryToProject("typing", ""); myFixture.configureByFile(TEST_DIRECTORY + getTestName(false) + ".py"); myFixture.enableInspections(PyTypeCheckerInspection.class); myFixture.checkHighlighting(true, false, true); @@ -42,10 +43,11 @@ public class Py3TypeCheckerInspectionTest extends PyTestCase { } private void doMultiFileTest() { - runWithLanguageLevel(LanguageLevel.PYTHON32, new Runnable() { + runWithLanguageLevel(LanguageLevel.PYTHON35, new Runnable() { @Override public void run() { myFixture.copyDirectoryToProject(TEST_DIRECTORY + getTestName(false), ""); + myFixture.copyDirectoryToProject("typing", ""); myFixture.configureFromTempProjectFile("a.py"); myFixture.enableInspections(PyTypeCheckerInspection.class); myFixture.checkHighlighting(true, false, true); @@ -66,4 +68,14 @@ public class Py3TypeCheckerInspectionTest extends PyTestCase { public void testBuiltinsPy3() { doTest(); } + + // PY-16125 + public void testTypingIterableForLoop() { + doTest(); + } + + // PY-16146 + public void testTypingListSubscriptionExpression() { + doTest(); + } } diff --git a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java index 59a93465d995..eea37a2e7b6a 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java @@ -510,7 +510,10 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase { doTest(); } - + // PY-16146 + public void testUnresolvedSubscriptionOnClass() { + doTest(); + } @NotNull @Override diff --git a/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java b/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java index e0a866528484..0fab31bccd9c 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java @@ -632,7 +632,13 @@ public class HtmlUtil { } public static boolean supportsXmlTypedHandlers(PsiFile file) { - return "JavaScript".equals(file.getLanguage().getID()); + Language language = file.getLanguage(); + while (language != null) { + if ("JavaScript".equals(language.getID())) return true; + language = language.getBaseLanguage(); + } + + return false; } public static boolean hasHtmlPrefix(@NotNull String url) {