Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2014-10-31 13:33:17 +01:00
14 changed files with 108 additions and 24 deletions
@@ -166,10 +166,7 @@ public class PsiTypesUtil {
qualifierType = JavaPsiFacade.getInstance(project).getElementFactory().createType((PsiClass)parent.getPsi());
}
}
PsiElement parent = call.getParent();
boolean captureTopLevelWildcards = parent instanceof PsiReferenceExpression && parent.getParent() instanceof PsiMethodCallExpression ||
parent instanceof PsiExpressionList;
return createJavaLangClassType(methodExpression, qualifierType, captureTopLevelWildcards);
return createJavaLangClassType(methodExpression, qualifierType, true);
}
return null;
}
@@ -17,6 +17,7 @@ package com.intellij.psi.impl.source.resolve.graphInference.constraints;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.NotNull;
@@ -72,7 +73,12 @@ public class TypeCompatibilityConstraint implements ConstraintFormula {
final PsiClass sClass = sResult.getElement();
if (tClass != null && sClass != null) {
final PsiSubstitutor sSubstitutor = TypeConversionUtil.getClassSubstitutor(tClass, sClass, sResult.getSubstitutor());
if (sSubstitutor != null && PsiUtil.isRawSubstitutor(tClass, sSubstitutor)) {
if (sSubstitutor != null) {
if (PsiUtil.isRawSubstitutor(tClass, sSubstitutor)) {
return true;
}
}
else if (tClass instanceof InferenceVariable && ((PsiClassType)s).isRaw() && tClass.isInheritor(sClass, true)) {
return true;
}
}
@@ -11,3 +11,18 @@ class Example {
return getClass() == obj.getClass();
}
}
class Foo<T> {
public static Class<? extends Foo<?>> fFoo(final Foo<?> foo) {
<error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Foo>>', required: 'java.lang.Class<? extends Foo<?>>'">Class<? extends Foo<?>> fooClass = foo.getClass();</error>
<error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Foo>>', required: 'java.lang.Class<? extends Foo<?>>'">fooClass = foo.getClass()</error>;
<error descr="Incompatible types. Found: 'java.lang.Class<? extends Foo>', required: 'java.lang.Class<? extends Foo<?>>'">return foo.getClass();</error>
}
public static Class<? extends Foo<? extends String>> fFoo1(final Foo<? extends String> foo) {
<error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Foo>>', required: 'java.lang.Class<? extends Foo<? extends java.lang.String>>'">Class<? extends Foo<? extends String>> fooClass = foo.getClass();</error>
<error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Foo>>', required: 'java.lang.Class<? extends Foo<? extends java.lang.String>>'">fooClass = foo.getClass()</error>;
<error descr="Incompatible types. Found: 'java.lang.Class<? extends Foo>', required: 'java.lang.Class<? extends Foo<? extends java.lang.String>>'">return foo.getClass();</error>
}
}
@@ -60,8 +60,8 @@ abstract class C {
try { g(); }
catch (IE1 | IE2 e) {
Class<? extends E> clazz1 = e.getClass();
<error descr="Incompatible types. Found: 'java.lang.Class<? extends C.E>', required: 'java.lang.Class<? extends C.IE1>'">Class<? extends IE1> clazz2 = e.getClass();</error>
<error descr="Incompatible types. Found: 'java.lang.Class<? extends C.E>', required: 'java.lang.Class<? extends C.I>'">Class<? extends I> clazz3 = e.getClass();</error>
<error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends C.E>>', required: 'java.lang.Class<? extends C.IE1>'">Class<? extends IE1> clazz2 = e.getClass();</error>
<error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends C.E>>', required: 'java.lang.Class<? extends C.I>'">Class<? extends I> clazz3 = e.getClass();</error>
}
try { f(); }
@@ -0,0 +1,13 @@
import java.util.List;
class Foo<Bazz> {
public void test(Foo parent) {
<error descr="Incompatible types. Found: 'java.lang.Object', required: 'Foo'">Foo foo = getElements(parent).get(0);</error>
}
public static <E extends Foo<E>> List<E> getElements(E parent) {
return null;
}
}
@@ -255,6 +255,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
doTest();
}
public void testUncheckedConversionWithRecursiveTypeParams() throws Exception {
doTest(false);
}
private void doTest() throws Exception {
doTest(false);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

@@ -41,10 +41,50 @@ import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
/**
* Utility to patch project model by excluding folders/files from content roots.
* Can be used for running offline inspections (from command-line directly or in teamcity).
*
* The main logic is in the method {@link #patchProject(com.intellij.openapi.project.Project)}.
*
* @see com.intellij.codeInspection.InspectionApplication
*/
public class PatchProjectUtil {
private PatchProjectUtil() {
}
/**
* Excludes folders specified in patterns in the <code>idea.exclude.patterns</code> system property from the project.
*
* <p>Pattern syntax:
* <br>
*
* <ul>
* <li><code>patterns := pattern(';'pattern)*</code>
* <li><code>pattern := ('['moduleRegEx']')? directoryAntPattern</code>
* </ul>
*
* Where
* <ul>
* <li> <code>moduleRegex</code> - regular expression to match module name.
* <li> <code>directoryAntPattern</code> - ant-style pattern to match folder in a module.
* <code>directoryAntPattern</code> considers paths <b>relative</b> to a content root of a module.
* </ul>
*
*
* <p>
* Example:<br>
* <code>
* -Didea.exclude.patterns=testData/**;.reports/**;[sql]/test/*.sql;[graph]/**;[graph-openapi]/**
* </code>
* <br>
*
* In this example the <code>testData/**</code> pattern is applied to all modules
* and the pattern <code>/test/*.sql</code> to applied to the module <code>sql</code> only.
*
* @param project project to patch
* @see <a href="http://ant.apache.org/manual/dirtasks.html">http://ant.apache.org/manual/dirtasks.html</a>
*/
public static void patchProject(final Project project) {
final Map<Pattern, Set<Pattern>> excludePatterns = loadPatterns("idea.exclude.patterns");
final Map<Pattern, Set<Pattern>> includePatterns = loadPatterns("idea.include.patterns");
@@ -138,6 +178,13 @@ public class PatchProjectUtil {
});
}
/**
* Parses patterns for exclude items.
*
* @param propertyKey system property key for pattern
* @return A map in the form <code>ModulePattern -> DirectoryPattern*</code>.
* ModulePattern may be null (meaning that a directory pattern is applied to all modules).
*/
public static Map<Pattern, Set<Pattern>> loadPatterns(@NonNls String propertyKey) {
final Map<Pattern, Set<Pattern>> result = new HashMap<Pattern, Set<Pattern>>();
final String patterns = System.getProperty(propertyKey);
@@ -437,7 +437,7 @@ public final class ImmutableText extends ImmutableCharSequence implements CharAr
if (start == 0 && end == length()) {
return this;
}
return createLeafNode(subSequence(start, end));
return createLeafNode(new CharArrayCharSequence(data, start, end));
}
@NotNull
@@ -334,16 +334,16 @@ public class TypeOrElementOrAttributeReference implements PsiReference {
final XmlNSDescriptor nsDescriptor = tag.getNSDescriptor(namespace, true);
if (nsDescriptor instanceof XmlNSDescriptorImpl) {
processNamespace(namespace, processor, nsDescriptor, tagNames);
processNamespace(namespace, processor, (XmlNSDescriptorImpl)nsDescriptor, tagNames);
}
}
XmlNSDescriptor nsDescriptor = (XmlNSDescriptor)document.getMetaData();
if (nsDescriptor != null) {
if (nsDescriptor instanceof XmlNSDescriptorImpl) {
processNamespace(
ourNamespace,
processor,
nsDescriptor,
(XmlNSDescriptorImpl)nsDescriptor,
tagNames
);
}
@@ -353,13 +353,12 @@ public class TypeOrElementOrAttributeReference implements PsiReference {
private static void processNamespace(final String namespace,
final CompletionProcessor processor,
final XmlNSDescriptor nsDescriptor,
final XmlNSDescriptorImpl nsDescriptor,
final String[] tagNames) {
processor.namespace = namespace;
final XmlNSDescriptorImpl xmlNSDescriptor = ((XmlNSDescriptorImpl)nsDescriptor);
XmlNSDescriptorImpl.processTagsInNamespace(
xmlNSDescriptor.getTag(),
nsDescriptor.getTag(),
tagNames,
processor
);
@@ -117,11 +117,10 @@ public class XmlElementDescriptorImpl extends XsdEnumerationDescriptor<XmlTag>
public String getNamespace(){
String name = getName();
if (name == null) return XmlUtil.EMPTY_URI;
final XmlNSDescriptorImpl xmlNSDescriptor = (XmlNSDescriptorImpl)getNSDescriptor();
if (xmlNSDescriptor == null || myDescriptorTag == null) return XmlUtil.EMPTY_URI;
if (getNSDescriptor() == null || myDescriptorTag == null) return XmlUtil.EMPTY_URI;
final String namespacePrefix = XmlUtil.findPrefixByQualifiedName(name);
return namespacePrefix.isEmpty() ?
xmlNSDescriptor.getDefaultNamespace() :
getDefaultNamespace() :
myDescriptorTag.getNamespaceByPrefix(namespacePrefix);
}
@@ -192,7 +191,7 @@ public class XmlElementDescriptorImpl extends XsdEnumerationDescriptor<XmlTag>
if (substAttr != null) {
final String namespacePrefix = XmlUtil.findPrefixByQualifiedName(substAttr);
final String namespace = namespacePrefix.isEmpty() ?
((XmlNSDescriptorImpl)getNSDescriptor()).getDefaultNamespace() :
getDefaultNamespace() :
myDescriptorTag.getNamespaceByPrefix(namespacePrefix);
final String local = XmlUtil.findLocalNameByQualifiedName(substAttr);
final XmlElementDescriptorImpl originalElement = (XmlElementDescriptorImpl)((XmlNSDescriptorImpl)getNSDescriptor()).getElementDescriptor(local, namespace);
@@ -335,9 +334,8 @@ public class XmlElementDescriptorImpl extends XsdEnumerationDescriptor<XmlTag>
private XmlAttributeDescriptor getAttributeDescriptorImpl(final String attributeName, XmlTag context) {
final String localName = XmlUtil.findLocalNameByQualifiedName(attributeName);
final String namespacePrefix = XmlUtil.findPrefixByQualifiedName(attributeName);
final XmlNSDescriptorImpl xmlNSDescriptor = (XmlNSDescriptorImpl)getNSDescriptor();
final String namespace = namespacePrefix.isEmpty() ?
((xmlNSDescriptor != null)?xmlNSDescriptor.getDefaultNamespace():"") :
getDefaultNamespace() :
context.getNamespaceByPrefix(namespacePrefix);
XmlAttributeDescriptor attribute = getAttribute(localName, namespace, context, attributeName);
@@ -364,6 +362,11 @@ public class XmlElementDescriptorImpl extends XsdEnumerationDescriptor<XmlTag>
return attribute;
}
private String getDefaultNamespace() {
XmlNSDescriptor nsDescriptor = getNSDescriptor();
return nsDescriptor instanceof XmlNSDescriptorImpl ? ((XmlNSDescriptorImpl)nsDescriptor).getDefaultNamespace() : "";
}
@Override
public XmlAttributeDescriptor getAttributeDescriptor(XmlAttribute attribute){
return getAttributeDescriptorImpl(attribute.getName(),attribute.getParent());
@@ -410,7 +413,7 @@ public class XmlElementDescriptorImpl extends XsdEnumerationDescriptor<XmlTag>
final String localName = XmlUtil.findLocalNameByQualifiedName(name);
final String namespacePrefix = XmlUtil.findPrefixByQualifiedName(name);
final String namespace = namespacePrefix.isEmpty() ?
((XmlNSDescriptorImpl)getNSDescriptor()).getDefaultNamespace() :
getDefaultNamespace() :
myDescriptorTag.getNamespaceByPrefix(namespacePrefix);
return getElementDescriptor(localName, namespace, null, name);
}
@@ -477,10 +477,10 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
private XmlAttributeDescriptor getAttributeImpl(String localName, String namespace, @Nullable Set<XmlTag> visited) {
if (myTag == null) return null;
XmlNSDescriptorImpl nsDescriptor = (XmlNSDescriptorImpl)myTag.getNSDescriptor(namespace, true);
XmlNSDescriptor nsDescriptor = myTag.getNSDescriptor(namespace, true);
if (nsDescriptor != this && nsDescriptor != null) {
return nsDescriptor.getAttributeImpl(
if (nsDescriptor != this && nsDescriptor instanceof XmlNSDescriptorImpl) {
return ((XmlNSDescriptorImpl)nsDescriptor).getAttributeImpl(
localName,
namespace,
visited