List of usage examples for org.eclipse.jdt.internal.compiler.lookup TypeBinding isWildcard
public boolean isWildcard()
From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.PatternLocator.java
License:Open Source License
protected void updateMatch(TypeBinding[] argumentsBinding, MatchLocator locator, char[][] patternArguments, boolean hasTypeParameters) { // Only possible if locator has an unit scope. if (locator.unitScope == null) return;//from ww w . j a v a 2s. c o m // First compare lengthes int patternTypeArgsLength = patternArguments == null ? 0 : patternArguments.length; int typeArgumentsLength = argumentsBinding == null ? 0 : argumentsBinding.length; // Initialize match rule int matchRule = this.match.getRule(); if (this.match.isRaw()) { if (patternTypeArgsLength != 0) { matchRule &= ~SearchPattern.R_FULL_MATCH; } } if (hasTypeParameters) { matchRule = SearchPattern.R_ERASURE_MATCH; } // Compare arguments lengthes if (patternTypeArgsLength == typeArgumentsLength) { if (!this.match.isRaw() && hasTypeParameters) { // generic patterns are always not compatible match this.match.setRule(SearchPattern.R_ERASURE_MATCH); return; } } else { if (patternTypeArgsLength == 0) { if (!this.match.isRaw() || hasTypeParameters) { this.match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH); } } else if (typeArgumentsLength == 0) { // raw binding is always compatible this.match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH); } else { this.match.setRule(0); // impossible match } return; } if (argumentsBinding == null || patternArguments == null) { this.match.setRule(matchRule); return; } // Compare binding for each type argument only if pattern is not erasure only and at first level if (!hasTypeParameters && !this.match.isRaw() && (this.match.isEquivalent() || this.match.isExact())) { for (int i = 0; i < typeArgumentsLength; i++) { // Get parameterized type argument binding TypeBinding argumentBinding = argumentsBinding[i]; if (argumentBinding instanceof CaptureBinding) { WildcardBinding capturedWildcard = ((CaptureBinding) argumentBinding).wildcard; if (capturedWildcard != null) argumentBinding = capturedWildcard; } // Get binding for pattern argument char[] patternTypeArgument = patternArguments[i]; char patternWildcard = patternTypeArgument[0]; char[] patternTypeName = patternTypeArgument; int patternWildcardKind = -1; switch (patternWildcard) { case Signature.C_STAR: if (argumentBinding.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; if (wildcardBinding.boundKind == Wildcard.UNBOUND) continue; } matchRule &= ~SearchPattern.R_FULL_MATCH; continue; // unbound parameter always match case Signature.C_EXTENDS: patternWildcardKind = Wildcard.EXTENDS; patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length); break; case Signature.C_SUPER: patternWildcardKind = Wildcard.SUPER; patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length); break; default: break; } patternTypeName = Signature.toCharArray(patternTypeName); TypeBinding patternBinding = locator.getType(patternTypeArgument, patternTypeName); // If have no binding for pattern arg, then we won't be able to refine accuracy if (patternBinding == null) { if (argumentBinding.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; if (wildcardBinding.boundKind == Wildcard.UNBOUND) { matchRule &= ~SearchPattern.R_FULL_MATCH; } else { this.match.setRule(SearchPattern.R_ERASURE_MATCH); return; } } continue; } // Verify tha pattern binding is compatible with match type argument binding switch (patternWildcard) { case Signature.C_STAR: // UNBOUND pattern // unbound always match => skip to next argument matchRule &= ~SearchPattern.R_FULL_MATCH; continue; case Signature.C_EXTENDS: // EXTENDS pattern if (argumentBinding.isWildcard()) { // argument is a wildcard WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; // It's ok if wildcards are identical if (wildcardBinding.boundKind == patternWildcardKind && wildcardBinding.bound == patternBinding) { continue; } // Look for wildcard compatibility switch (wildcardBinding.boundKind) { case Wildcard.EXTENDS: if (wildcardBinding.bound == null || wildcardBinding.bound.isCompatibleWith(patternBinding)) { // valid when arg extends a subclass of pattern matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } break; case Wildcard.SUPER: break; case Wildcard.UNBOUND: matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } } else if (argumentBinding.isCompatibleWith(patternBinding)) { // valid when arg is a subclass of pattern matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } break; case Signature.C_SUPER: // SUPER pattern if (argumentBinding.isWildcard()) { // argument is a wildcard WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; // It's ok if wildcards are identical if (wildcardBinding.boundKind == patternWildcardKind && wildcardBinding.bound == patternBinding) { continue; } // Look for wildcard compatibility switch (wildcardBinding.boundKind) { case Wildcard.EXTENDS: break; case Wildcard.SUPER: if (wildcardBinding.bound == null || patternBinding.isCompatibleWith(wildcardBinding.bound)) { // valid only when arg super a superclass of pattern matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } break; case Wildcard.UNBOUND: matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } } else if (patternBinding.isCompatibleWith(argumentBinding)) { // valid only when arg is a superclass of pattern matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } break; default: if (argumentBinding.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; switch (wildcardBinding.boundKind) { case Wildcard.EXTENDS: if (wildcardBinding.bound == null || patternBinding.isCompatibleWith(wildcardBinding.bound)) { // valid only when arg extends a superclass of pattern matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } break; case Wildcard.SUPER: if (wildcardBinding.bound == null || wildcardBinding.bound.isCompatibleWith(patternBinding)) { // valid only when arg super a subclass of pattern matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } break; case Wildcard.UNBOUND: matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } } else if (argumentBinding == patternBinding) // valid only when arg is equals to pattern continue; break; } // Argument does not match => erasure match will be the only possible one this.match.setRule(SearchPattern.R_ERASURE_MATCH); return; } } // Set match rule this.match.setRule(matchRule); }
From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.PatternLocator.java
License:Open Source License
protected int resolveLevelForType(char[] simpleNamePattern, char[] qualificationPattern, char[][][] patternTypeArguments, int depth, TypeBinding type) { // standard search with no generic additional information must succeed int level = resolveLevelForType(simpleNamePattern, qualificationPattern, type); if (level == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH; if (type == null || patternTypeArguments == null || patternTypeArguments.length == 0 || depth >= patternTypeArguments.length) { return level; }/*from w ww .ja va 2 s . c om*/ // if pattern is erasure match (see bug 79790), commute impossible to erasure int impossible = this.isErasureMatch ? ERASURE_MATCH : IMPOSSIBLE_MATCH; // pattern has type parameter(s) or type argument(s) if (type.isGenericType()) { // Binding is generic, get its type variable(s) TypeVariableBinding[] typeVariables = null; if (type instanceof SourceTypeBinding) { SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) type; typeVariables = sourceTypeBinding.typeVariables; } else if (type instanceof BinaryTypeBinding) { BinaryTypeBinding binaryTypeBinding = (BinaryTypeBinding) type; if (this.mustResolve) typeVariables = binaryTypeBinding.typeVariables(); // TODO (frederic) verify performance } if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0 && typeVariables != null && typeVariables.length > 0) { if (typeVariables.length != patternTypeArguments[depth].length) return IMPOSSIBLE_MATCH; } // TODO (frederic) do we need to verify each parameter? return level; // we can't do better } // raw type always match if (type.isRawType()) { return level; } // Standard types (i.e. neither generic nor parameterized nor raw types) // cannot match pattern with type parameters or arguments TypeBinding leafType = type.leafComponentType(); if (!leafType.isParameterizedType()) { return (patternTypeArguments[depth] == null || patternTypeArguments[depth].length == 0) ? level : IMPOSSIBLE_MATCH; } // Parameterized type ParameterizedTypeBinding paramTypeBinding = (ParameterizedTypeBinding) leafType; // Compare arguments only if there ones on both sides if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0 && paramTypeBinding.arguments != null && paramTypeBinding.arguments.length > 0) { // type parameters length must match at least specified type names length int length = patternTypeArguments[depth].length; if (paramTypeBinding.arguments.length != length) return IMPOSSIBLE_MATCH; // verify each pattern type parameter nextTypeArgument: for (int i = 0; i < length; i++) { char[] patternTypeArgument = patternTypeArguments[depth][i]; TypeBinding argTypeBinding = paramTypeBinding.arguments[i]; // get corresponding pattern wildcard switch (patternTypeArgument[0]) { case Signature.C_STAR: // unbound parameter always match case Signature.C_SUPER: // needs pattern type parameter binding // skip to next type argument as it will be resolved later continue nextTypeArgument; case Signature.C_EXTENDS: // remove wildcard from patter type argument patternTypeArgument = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length); break; default: // no wildcard break; } // get pattern type argument from its signature patternTypeArgument = Signature.toCharArray(patternTypeArgument); if (!this.isCaseSensitive) patternTypeArgument = CharOperation.toLowerCase(patternTypeArgument); boolean patternTypeArgHasAnyChars = CharOperation.contains(new char[] { '*', '?' }, patternTypeArgument); // Verify that names match... // ...special case for wildcard if (argTypeBinding instanceof CaptureBinding) { WildcardBinding capturedWildcard = ((CaptureBinding) argTypeBinding).wildcard; if (capturedWildcard != null) argTypeBinding = capturedWildcard; } if (argTypeBinding.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) argTypeBinding; switch (wildcardBinding.boundKind) { case Wildcard.EXTENDS: // Invalid if type argument is not exact if (patternTypeArgHasAnyChars) return impossible; continue nextTypeArgument; case Wildcard.UNBOUND: // there's no bound name to match => valid continue nextTypeArgument; } // Look if bound name match pattern type argument ReferenceBinding boundBinding = (ReferenceBinding) wildcardBinding.bound; if (CharOperation.match(patternTypeArgument, boundBinding.shortReadableName(), this.isCaseSensitive) || CharOperation.match(patternTypeArgument, boundBinding.readableName(), this.isCaseSensitive)) { // found name in hierarchy => match continue nextTypeArgument; } // If pattern is not exact then match fails if (patternTypeArgHasAnyChars) return impossible; // Look for bound name in type argument superclasses boundBinding = boundBinding.superclass(); while (boundBinding != null) { if (CharOperation.equals(patternTypeArgument, boundBinding.shortReadableName(), this.isCaseSensitive) || CharOperation.equals(patternTypeArgument, boundBinding.readableName(), this.isCaseSensitive)) { // found name in hierarchy => match continue nextTypeArgument; } else if (boundBinding.isLocalType() || boundBinding.isMemberType()) { // for local or member type, verify also source name (bug 81084) if (CharOperation.match(patternTypeArgument, boundBinding.sourceName(), this.isCaseSensitive)) continue nextTypeArgument; } boundBinding = boundBinding.superclass(); } return impossible; } // See if names match if (CharOperation.match(patternTypeArgument, argTypeBinding.shortReadableName(), this.isCaseSensitive) || CharOperation.match(patternTypeArgument, argTypeBinding.readableName(), this.isCaseSensitive)) { continue nextTypeArgument; } else if (argTypeBinding.isLocalType() || argTypeBinding.isMemberType()) { // for local or member type, verify also source name (bug 81084) if (CharOperation.match(patternTypeArgument, argTypeBinding.sourceName(), this.isCaseSensitive)) continue nextTypeArgument; } // If pattern is not exact then match fails if (patternTypeArgHasAnyChars) return impossible; // Scan hierarchy TypeBinding leafTypeBinding = argTypeBinding.leafComponentType(); if (leafTypeBinding.isBaseType()) return impossible; ReferenceBinding refBinding = ((ReferenceBinding) leafTypeBinding).superclass(); while (refBinding != null) { if (CharOperation.equals(patternTypeArgument, refBinding.shortReadableName(), this.isCaseSensitive) || CharOperation.equals(patternTypeArgument, refBinding.readableName(), this.isCaseSensitive)) { // found name in hierarchy => match continue nextTypeArgument; } else if (refBinding.isLocalType() || refBinding.isMemberType()) { // for local or member type, verify also source name (bug 81084) if (CharOperation.match(patternTypeArgument, refBinding.sourceName(), this.isCaseSensitive)) continue nextTypeArgument; } refBinding = refBinding.superclass(); } return impossible; } } // Recurse on enclosing type TypeBinding enclosingType = paramTypeBinding.enclosingType(); if (enclosingType != null && enclosingType.isParameterizedType() && depth < patternTypeArguments.length && qualificationPattern != null) { int lastDot = CharOperation.lastIndexOf('.', qualificationPattern); char[] enclosingQualificationPattern = lastDot == -1 ? null : CharOperation.subarray(qualificationPattern, 0, lastDot); char[] enclosingSimpleNamePattern = lastDot == -1 ? qualificationPattern : CharOperation.subarray(qualificationPattern, lastDot + 1, qualificationPattern.length); int enclosingLevel = resolveLevelForType(enclosingSimpleNamePattern, enclosingQualificationPattern, patternTypeArguments, depth + 1, enclosingType); if (enclosingLevel == impossible) return impossible; if (enclosingLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH; } return level; }
From source file:com.redhat.ceylon.eclipse.core.model.mirror.UnknownTypeMirror.java
License:Open Source License
public JDTType(TypeBinding type, IdentityHashMap<TypeBinding, JDTType> originatingTypes) { originatingTypes.put(type, this); // type params are not qualified if (type instanceof TypeVariableBinding) qualifiedName = new String(type.qualifiedSourceName()); else//from w w w.j av a 2 s . c om qualifiedName = JDTUtils.getFullyQualifiedName(type); typeKind = findKind(type); isPrimitive = type.isBaseType() && type.id != TypeIds.T_void && type.id != TypeIds.T_null; isRaw = type.isRawType(); if (type instanceof ParameterizedTypeBinding && !(type instanceof RawTypeBinding)) { TypeBinding[] javaTypeArguments = ((ParameterizedTypeBinding) type).arguments; if (javaTypeArguments == null) { javaTypeArguments = new TypeBinding[0]; } typeArguments = new ArrayList<TypeMirror>(javaTypeArguments.length); for (TypeBinding typeArgument : javaTypeArguments) typeArguments.add(toTypeMirror(typeArgument, type, this, originatingTypes)); } else { typeArguments = Collections.emptyList(); } if (type instanceof ArrayBinding) { TypeBinding jdtComponentType = ((ArrayBinding) type).elementsType(); componentType = toTypeMirror(jdtComponentType, type, this, originatingTypes); } else { componentType = null; } if (type.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) type; if (wildcardBinding.boundKind == Wildcard.EXTENDS) { TypeBinding upperBoundBinding = wildcardBinding.bound; if (upperBoundBinding != null) { upperBound = toTypeMirror(upperBoundBinding, type, this, originatingTypes); } } } else if (type.isTypeVariable()) { TypeVariableBinding typeVariableBinding = (TypeVariableBinding) type; TypeBinding boundBinding = typeVariableBinding.firstBound; // TODO : we should confirm this if (boundBinding != null) { upperBound = toTypeMirror(boundBinding, type, this, originatingTypes); } } else { upperBound = null; } if (type.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) type; if (wildcardBinding.boundKind == Wildcard.SUPER) { TypeBinding lowerBoundBinding = wildcardBinding.bound; if (lowerBoundBinding != null) { lowerBound = toTypeMirror(lowerBoundBinding, type, this, originatingTypes); } } } if (type instanceof ParameterizedTypeBinding || type instanceof SourceTypeBinding || type instanceof BinaryTypeBinding) { ReferenceBinding refBinding = (ReferenceBinding) type; declaredClass = new JDTClass(refBinding, JDTModelLoader.toType(refBinding)); } if (type instanceof TypeVariableBinding) { typeParameter = new JDTTypeParameter((TypeVariableBinding) type, this, originatingTypes); } }
From source file:lombok.eclipse.handlers.EclipseHandlerUtil.java
License:Open Source License
public static TypeReference makeType(TypeBinding binding, ASTNode pos, boolean allowCompound) { int dims = binding.dimensions(); binding = binding.leafComponentType(); // Primitives char[] base = null; switch (binding.id) { case TypeIds.T_int: base = TypeConstants.INT;/*from w w w. ja v a 2s . c o m*/ break; case TypeIds.T_long: base = TypeConstants.LONG; break; case TypeIds.T_short: base = TypeConstants.SHORT; break; case TypeIds.T_byte: base = TypeConstants.BYTE; break; case TypeIds.T_double: base = TypeConstants.DOUBLE; break; case TypeIds.T_float: base = TypeConstants.FLOAT; break; case TypeIds.T_boolean: base = TypeConstants.BOOLEAN; break; case TypeIds.T_char: base = TypeConstants.CHAR; break; case TypeIds.T_void: base = TypeConstants.VOID; break; case TypeIds.T_null: return null; } if (base != null) { if (dims > 0) { TypeReference result = new ArrayTypeReference(base, dims, pos(pos)); setGeneratedBy(result, pos); return result; } TypeReference result = new SingleTypeReference(base, pos(pos)); setGeneratedBy(result, pos); return result; } if (binding.isAnonymousType()) { ReferenceBinding ref = (ReferenceBinding) binding; ReferenceBinding[] supers = ref.superInterfaces(); if (supers == null || supers.length == 0) supers = new ReferenceBinding[] { ref.superclass() }; if (supers[0] == null) { TypeReference result = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3)); setGeneratedBy(result, pos); return result; } return makeType(supers[0], pos, false); } if (binding instanceof CaptureBinding) { return makeType(((CaptureBinding) binding).wildcard, pos, allowCompound); } if (binding.isUnboundWildcard()) { if (!allowCompound) { TypeReference result = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3)); setGeneratedBy(result, pos); return result; } else { Wildcard out = new Wildcard(Wildcard.UNBOUND); setGeneratedBy(out, pos); out.sourceStart = pos.sourceStart; out.sourceEnd = pos.sourceEnd; return out; } } if (binding.isWildcard()) { WildcardBinding wildcard = (WildcardBinding) binding; if (wildcard.boundKind == Wildcard.EXTENDS) { if (!allowCompound) { return makeType(wildcard.bound, pos, false); } else { Wildcard out = new Wildcard(Wildcard.EXTENDS); setGeneratedBy(out, pos); out.bound = makeType(wildcard.bound, pos, false); out.sourceStart = pos.sourceStart; out.sourceEnd = pos.sourceEnd; return out; } } else if (allowCompound && wildcard.boundKind == Wildcard.SUPER) { Wildcard out = new Wildcard(Wildcard.SUPER); setGeneratedBy(out, pos); out.bound = makeType(wildcard.bound, pos, false); out.sourceStart = pos.sourceStart; out.sourceEnd = pos.sourceEnd; return out; } else { TypeReference result = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3)); setGeneratedBy(result, pos); return result; } } // Keep moving up via 'binding.enclosingType()' and gather generics from each binding. We stop after a local type, or a static type, or a top-level type. // Finally, add however many nullTypeArgument[] arrays as that are missing, inverse the list, toArray it, and use that as PTR's typeArgument argument. List<TypeReference[]> params = new ArrayList<TypeReference[]>(); /* Calculate generics */ { TypeBinding b = binding; while (true) { boolean isFinalStop = b.isLocalType() || !b.isMemberType() || b.enclosingType() == null; TypeReference[] tyParams = null; if (b instanceof ParameterizedTypeBinding) { ParameterizedTypeBinding paramized = (ParameterizedTypeBinding) b; if (paramized.arguments != null) { tyParams = new TypeReference[paramized.arguments.length]; for (int i = 0; i < tyParams.length; i++) { tyParams[i] = makeType(paramized.arguments[i], pos, true); } } } params.add(tyParams); if (isFinalStop) break; b = b.enclosingType(); } } char[][] parts; if (binding.isTypeVariable()) { parts = new char[][] { binding.shortReadableName() }; } else if (binding.isLocalType()) { parts = new char[][] { binding.sourceName() }; } else { String[] pkg = new String(binding.qualifiedPackageName()).split("\\."); String[] name = new String(binding.qualifiedSourceName()).split("\\."); if (pkg.length == 1 && pkg[0].isEmpty()) pkg = new String[0]; parts = new char[pkg.length + name.length][]; int ptr; for (ptr = 0; ptr < pkg.length; ptr++) parts[ptr] = pkg[ptr].toCharArray(); for (; ptr < pkg.length + name.length; ptr++) parts[ptr] = name[ptr - pkg.length].toCharArray(); } while (params.size() < parts.length) params.add(null); Collections.reverse(params); boolean isParamized = false; for (TypeReference[] tyParams : params) { if (tyParams != null) { isParamized = true; break; } } if (isParamized) { if (parts.length > 1) { TypeReference[][] typeArguments = params.toArray(new TypeReference[0][]); TypeReference result = new ParameterizedQualifiedTypeReference(parts, typeArguments, dims, poss(pos, parts.length)); setGeneratedBy(result, pos); return result; } TypeReference result = new ParameterizedSingleTypeReference(parts[0], params.get(0), dims, pos(pos)); setGeneratedBy(result, pos); return result; } if (dims > 0) { if (parts.length > 1) { TypeReference result = new ArrayQualifiedTypeReference(parts, dims, poss(pos, parts.length)); setGeneratedBy(result, pos); return result; } TypeReference result = new ArrayTypeReference(parts[0], dims, pos(pos)); setGeneratedBy(result, pos); return result; } if (parts.length > 1) { TypeReference result = new QualifiedTypeReference(parts, poss(pos, parts.length)); setGeneratedBy(result, pos); return result; } TypeReference result = new SingleTypeReference(parts[0], pos(pos)); setGeneratedBy(result, pos); return result; }
From source file:org.eclipse.che.jdt.internal.core.search.matching.PatternLocator.java
License:Open Source License
protected void updateMatch(TypeBinding[] argumentsBinding, MatchLocator locator, char[][] patternArguments, boolean hasTypeParameters) { // Only possible if locator has an unit scope. if (locator.unitScope == null) return;//from w ww. ja va2s . co m // First compare lengthes int patternTypeArgsLength = patternArguments == null ? 0 : patternArguments.length; int typeArgumentsLength = argumentsBinding == null ? 0 : argumentsBinding.length; // Initialize match rule int matchRule = this.match.getRule(); if (this.match.isRaw()) { if (patternTypeArgsLength != 0) { matchRule &= ~SearchPattern.R_FULL_MATCH; } } if (hasTypeParameters) { matchRule = SearchPattern.R_ERASURE_MATCH; } // Compare arguments lengthes if (patternTypeArgsLength == typeArgumentsLength) { if (!this.match.isRaw() && hasTypeParameters) { // generic patterns are always not compatible match this.match.setRule(SearchPattern.R_ERASURE_MATCH); return; } } else { if (patternTypeArgsLength == 0) { if (!this.match.isRaw() || hasTypeParameters) { this.match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH); } } else if (typeArgumentsLength == 0) { // raw binding is always compatible this.match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH); } else { this.match.setRule(0); // impossible match } return; } if (argumentsBinding == null || patternArguments == null) { this.match.setRule(matchRule); return; } // Compare binding for each type argument only if pattern is not erasure only and at first level if (!hasTypeParameters && !this.match.isRaw() && (this.match.isEquivalent() || this.match.isExact())) { for (int i = 0; i < typeArgumentsLength; i++) { // Get parameterized type argument binding TypeBinding argumentBinding = argumentsBinding[i]; if (argumentBinding instanceof CaptureBinding) { WildcardBinding capturedWildcard = ((CaptureBinding) argumentBinding).wildcard; if (capturedWildcard != null) argumentBinding = capturedWildcard; } // Get binding for pattern argument char[] patternTypeArgument = patternArguments[i]; char patternWildcard = patternTypeArgument[0]; char[] patternTypeName = patternTypeArgument; int patternWildcardKind = -1; switch (patternWildcard) { case Signature.C_STAR: if (argumentBinding.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; if (wildcardBinding.boundKind == Wildcard.UNBOUND) continue; } matchRule &= ~SearchPattern.R_FULL_MATCH; continue; // unbound parameter always match case Signature.C_EXTENDS: patternWildcardKind = Wildcard.EXTENDS; patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length); break; case Signature.C_SUPER: patternWildcardKind = Wildcard.SUPER; patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length); break; default: break; } patternTypeName = Signature.toCharArray(patternTypeName); TypeBinding patternBinding = locator.getType(patternTypeArgument, patternTypeName); // If have no binding for pattern arg, then we won't be able to refine accuracy if (patternBinding == null) { if (argumentBinding.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; if (wildcardBinding.boundKind == Wildcard.UNBOUND) { matchRule &= ~SearchPattern.R_FULL_MATCH; } else { this.match.setRule(SearchPattern.R_ERASURE_MATCH); return; } } continue; } // Verify the pattern binding is compatible with match type argument binding switch (patternWildcard) { case Signature.C_STAR: // UNBOUND pattern // unbound always match => skip to next argument matchRule &= ~SearchPattern.R_FULL_MATCH; continue; case Signature.C_EXTENDS: // EXTENDS pattern if (argumentBinding.isWildcard()) { // argument is a wildcard WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; // It's ok if wildcards are identical if (wildcardBinding.boundKind == patternWildcardKind && TypeBinding.equalsEquals(wildcardBinding.bound, patternBinding)) { continue; } // Look for wildcard compatibility switch (wildcardBinding.boundKind) { case Wildcard.EXTENDS: if (wildcardBinding.bound == null || wildcardBinding.bound.isCompatibleWith(patternBinding)) { // valid when arg extends a subclass of pattern matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } break; case Wildcard.SUPER: break; case Wildcard.UNBOUND: matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } } else if (argumentBinding.isCompatibleWith(patternBinding)) { // valid when arg is a subclass of pattern matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } break; case Signature.C_SUPER: // SUPER pattern if (argumentBinding.isWildcard()) { // argument is a wildcard WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; // It's ok if wildcards are identical if (wildcardBinding.boundKind == patternWildcardKind && TypeBinding.equalsEquals(wildcardBinding.bound, patternBinding)) { continue; } // Look for wildcard compatibility switch (wildcardBinding.boundKind) { case Wildcard.EXTENDS: break; case Wildcard.SUPER: if (wildcardBinding.bound == null || patternBinding.isCompatibleWith(wildcardBinding.bound)) { // valid only when arg super a superclass of pattern matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } break; case Wildcard.UNBOUND: matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } } else if (patternBinding.isCompatibleWith(argumentBinding)) { // valid only when arg is a superclass of pattern matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } break; default: if (argumentBinding.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; switch (wildcardBinding.boundKind) { case Wildcard.EXTENDS: if (wildcardBinding.bound == null || patternBinding.isCompatibleWith(wildcardBinding.bound)) { // valid only when arg extends a superclass of pattern matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } break; case Wildcard.SUPER: if (wildcardBinding.bound == null || wildcardBinding.bound.isCompatibleWith(patternBinding)) { // valid only when arg super a subclass of pattern matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } break; case Wildcard.UNBOUND: matchRule &= ~SearchPattern.R_FULL_MATCH; continue; } } else if (TypeBinding.equalsEquals(argumentBinding, patternBinding)) // valid only when arg is equals to pattern continue; break; } // Argument does not match => erasure match will be the only possible one this.match.setRule(SearchPattern.R_ERASURE_MATCH); return; } } // Set match rule this.match.setRule(matchRule); }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
private TypeBinding leastContainingTypeArgument(TypeBinding u, TypeBinding v, ReferenceBinding genericType, int rank, List lubStack) { if (u == null) return v; if (u == v)/*from w w w.ja va 2 s . c o m*/ return u; if (v.isWildcard()) { WildcardBinding wildV = (WildcardBinding) v; if (u.isWildcard()) { WildcardBinding wildU = (WildcardBinding) u; switch (wildU.boundKind) { // ? extends U case Wildcard.EXTENDS: switch (wildV.boundKind) { // ? extends U, ? extends V case Wildcard.EXTENDS: TypeBinding lub = lowerUpperBound(new TypeBinding[] { wildU.bound, wildV.bound }, lubStack); if (lub == null) return null; // int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND); return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS); // ? extends U, ? SUPER V case Wildcard.SUPER: if (wildU.bound == wildV.bound) return wildU.bound; return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND); } break; // ? super U case Wildcard.SUPER: // ? super U, ? super V if (wildU.boundKind == Wildcard.SUPER) { TypeBinding[] glb = greaterLowerBound(new TypeBinding[] { wildU.bound, wildV.bound }); if (glb == null) return null; return environment().createWildcard(genericType, rank, glb[0], null /*no extra bound*/, Wildcard.SUPER); // TODO (philippe) need to capture entire bounds } } } else { switch (wildV.boundKind) { // U, ? extends V case Wildcard.EXTENDS: TypeBinding lub = lowerUpperBound(new TypeBinding[] { u, wildV.bound }, lubStack); if (lub == null) return null; // int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND); return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS); // U, ? super V case Wildcard.SUPER: TypeBinding[] glb = greaterLowerBound(new TypeBinding[] { u, wildV.bound }); if (glb == null) return null; return environment().createWildcard(genericType, rank, glb[0], null /*no extra bound*/, Wildcard.SUPER); // TODO (philippe) need to capture entire bounds case Wildcard.UNBOUND: } } } else if (u.isWildcard()) { WildcardBinding wildU = (WildcardBinding) u; switch (wildU.boundKind) { // U, ? extends V case Wildcard.EXTENDS: TypeBinding lub = lowerUpperBound(new TypeBinding[] { wildU.bound, v }, lubStack); if (lub == null) return null; // int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND); return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS); // U, ? super V case Wildcard.SUPER: TypeBinding[] glb = greaterLowerBound(new TypeBinding[] { wildU.bound, v }); if (glb == null) return null; return environment().createWildcard(genericType, rank, glb[0], null /*no extra bound*/, Wildcard.SUPER); // TODO (philippe) need to capture entire bounds case Wildcard.UNBOUND: } } TypeBinding lub = lowerUpperBound(new TypeBinding[] { u, v }, lubStack); if (lub == null) return null; // int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND); return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS); }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
/** * Returns the most specific set of types compatible with all given types. * (i.e. most specific common super types) * If no types is given, will return an empty array. If not compatible * reference type is found, returns null. In other cases, will return an array * of minimal erased types, where some nulls may appear (and must simply be * ignored).//w w w . j a va 2s . c o m */ protected TypeBinding[] minimalErasedCandidates(TypeBinding[] types, Map allInvocations) { int length = types.length; int indexOfFirst = -1, actualLength = 0; for (int i = 0; i < length; i++) { TypeBinding type = types[i]; if (type == null) continue; if (type.isBaseType()) return null; if (indexOfFirst < 0) indexOfFirst = i; actualLength++; } switch (actualLength) { case 0: return Binding.NO_TYPES; case 1: return types; } TypeBinding firstType = types[indexOfFirst]; if (firstType.isBaseType()) return null; // record all supertypes of type // intersect with all supertypes of otherType ArrayList typesToVisit = new ArrayList(5); int dim = firstType.dimensions(); TypeBinding leafType = firstType.leafComponentType(); // do not allow type variables/intersection types to match with erasures for free TypeBinding firstErasure; switch (leafType.kind()) { case Binding.PARAMETERIZED_TYPE: case Binding.RAW_TYPE: case Binding.ARRAY_TYPE: firstErasure = firstType.erasure(); break; default: firstErasure = firstType; break; } if (firstErasure != firstType) { allInvocations.put(firstErasure, firstType); } typesToVisit.add(firstType); int max = 1; ReferenceBinding currentType; for (int i = 0; i < max; i++) { TypeBinding typeToVisit = (TypeBinding) typesToVisit.get(i); dim = typeToVisit.dimensions(); if (dim > 0) { leafType = typeToVisit.leafComponentType(); switch (leafType.id) { case TypeIds.T_JavaLangObject: if (dim > 1) { // Object[][] supertype is Object[] TypeBinding elementType = ((ArrayBinding) typeToVisit).elementsType(); if (!typesToVisit.contains(elementType)) { typesToVisit.add(elementType); max++; } continue; } //$FALL-THROUGH$ case TypeIds.T_byte: case TypeIds.T_short: case TypeIds.T_char: case TypeIds.T_boolean: case TypeIds.T_int: case TypeIds.T_long: case TypeIds.T_float: case TypeIds.T_double: TypeBinding superType = getJavaIoSerializable(); if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; } superType = getJavaLangCloneable(); if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; } superType = getJavaLangObject(); if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; } continue; default: } typeToVisit = leafType; } currentType = (ReferenceBinding) typeToVisit; if (currentType.isCapture()) { TypeBinding firstBound = ((CaptureBinding) currentType).firstBound; if (firstBound != null && firstBound.isArrayType()) { TypeBinding superType = dim == 0 ? firstBound : (TypeBinding) environment().createArrayType(firstBound, dim); // recreate array if needed if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; TypeBinding superTypeErasure = (firstBound.isTypeVariable() || firstBound.isWildcard() /*&& !itsInterface.isCapture()*/) ? superType : superType.erasure(); if (superTypeErasure != superType) { allInvocations.put(superTypeErasure, superType); } } continue; } } // inject super interfaces prior to superclass ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); if (itsInterfaces != null) { // can be null during code assist operations that use LookupEnvironment.completeTypeBindings(parsedUnit, buildFieldsAndMethods) for (int j = 0, count = itsInterfaces.length; j < count; j++) { TypeBinding itsInterface = itsInterfaces[j]; TypeBinding superType = dim == 0 ? itsInterface : (TypeBinding) environment().createArrayType(itsInterface, dim); // recreate array if needed if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; TypeBinding superTypeErasure = (itsInterface.isTypeVariable() || itsInterface.isWildcard() /*&& !itsInterface.isCapture()*/) ? superType : superType.erasure(); if (superTypeErasure != superType) { allInvocations.put(superTypeErasure, superType); } } } } TypeBinding itsSuperclass = currentType.superclass(); if (itsSuperclass != null) { TypeBinding superType = dim == 0 ? itsSuperclass : (TypeBinding) environment().createArrayType(itsSuperclass, dim); // recreate array if needed if (!typesToVisit.contains(superType)) { typesToVisit.add(superType); max++; TypeBinding superTypeErasure = (itsSuperclass.isTypeVariable() || itsSuperclass.isWildcard() /*&& !itsSuperclass.isCapture()*/) ? superType : superType.erasure(); if (superTypeErasure != superType) { allInvocations.put(superTypeErasure, superType); } } } } int superLength = typesToVisit.size(); TypeBinding[] erasedSuperTypes = new TypeBinding[superLength]; int rank = 0; for (Iterator iter = typesToVisit.iterator(); iter.hasNext();) { TypeBinding type = (TypeBinding) iter.next(); leafType = type.leafComponentType(); erasedSuperTypes[rank++] = (leafType.isTypeVariable() || leafType.isWildcard() /*&& !leafType.isCapture()*/) ? type : type.erasure(); } // intersecting first type supertypes with other types' ones, nullifying non matching supertypes int remaining = superLength; nextOtherType: for (int i = indexOfFirst + 1; i < length; i++) { TypeBinding otherType = types[i]; if (otherType == null) continue nextOtherType; if (otherType.isArrayType()) { nextSuperType: for (int j = 0; j < superLength; j++) { TypeBinding erasedSuperType = erasedSuperTypes[j]; if (erasedSuperType == null || erasedSuperType == otherType) continue nextSuperType; TypeBinding match; if ((match = otherType.findSuperTypeOriginatingFrom(erasedSuperType)) == null) { erasedSuperTypes[j] = null; if (--remaining == 0) return null; continue nextSuperType; } // record invocation Object invocationData = allInvocations.get(erasedSuperType); if (invocationData == null) { allInvocations.put(erasedSuperType, match); // no array for singleton } else if (invocationData instanceof TypeBinding) { if (match != invocationData) { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = { (TypeBinding) invocationData, match, }; allInvocations.put(erasedSuperType, someInvocations); } } else { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = (TypeBinding[]) invocationData; checkExisting: { int invocLength = someInvocations.length; for (int k = 0; k < invocLength; k++) { if (someInvocations[k] == match) break checkExisting; } System.arraycopy(someInvocations, 0, someInvocations = new TypeBinding[invocLength + 1], 0, invocLength); allInvocations.put(erasedSuperType, someInvocations); someInvocations[invocLength] = match; } } } continue nextOtherType; } nextSuperType: for (int j = 0; j < superLength; j++) { TypeBinding erasedSuperType = erasedSuperTypes[j]; if (erasedSuperType == null) continue nextSuperType; TypeBinding match; if (erasedSuperType == otherType || erasedSuperType.id == TypeIds.T_JavaLangObject && otherType.isInterface()) { match = erasedSuperType; } else { if (erasedSuperType.isArrayType()) { match = null; } else { match = otherType.findSuperTypeOriginatingFrom(erasedSuperType); } if (match == null) { // incompatible super type erasedSuperTypes[j] = null; if (--remaining == 0) return null; continue nextSuperType; } } // record invocation Object invocationData = allInvocations.get(erasedSuperType); if (invocationData == null) { allInvocations.put(erasedSuperType, match); // no array for singleton } else if (invocationData instanceof TypeBinding) { if (match != invocationData) { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = { (TypeBinding) invocationData, match, }; allInvocations.put(erasedSuperType, someInvocations); } } else { // using an array to record invocations in order (188103) TypeBinding[] someInvocations = (TypeBinding[]) invocationData; checkExisting: { int invocLength = someInvocations.length; for (int k = 0; k < invocLength; k++) { if (someInvocations[k] == match) break checkExisting; } System.arraycopy(someInvocations, 0, someInvocations = new TypeBinding[invocLength + 1], 0, invocLength); allInvocations.put(erasedSuperType, someInvocations); someInvocations[invocLength] = match; } } } } // eliminate non minimal super types if (remaining > 1) { nextType: for (int i = 0; i < superLength; i++) { TypeBinding erasedSuperType = erasedSuperTypes[i]; if (erasedSuperType == null) continue nextType; nextOtherType: for (int j = 0; j < superLength; j++) { if (i == j) continue nextOtherType; TypeBinding otherType = erasedSuperTypes[j]; if (otherType == null) continue nextOtherType; if (erasedSuperType instanceof ReferenceBinding) { if (otherType.id == TypeIds.T_JavaLangObject && erasedSuperType.isInterface()) continue nextOtherType; // keep Object for an interface if (erasedSuperType.findSuperTypeOriginatingFrom(otherType) != null) { erasedSuperTypes[j] = null; // discard non minimal supertype remaining--; } } else if (erasedSuperType.isArrayType()) { if (otherType.isArrayType() // keep Object[...] for an interface array (same dimensions) && otherType.leafComponentType().id == TypeIds.T_JavaLangObject && otherType.dimensions() == erasedSuperType.dimensions() && erasedSuperType.leafComponentType().isInterface()) continue nextOtherType; if (erasedSuperType.findSuperTypeOriginatingFrom(otherType) != null) { erasedSuperTypes[j] = null; // discard non minimal supertype remaining--; } } } } } return erasedSuperTypes; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.AstGenerator.java
License:Open Source License
private TypeReference createArrayTypeReference(TypeBinding elementType, int dims, boolean makeGeneric) { // check generics: if (elementType.isTypeVariable()) { TypeVariableBinding typeVariable = (TypeVariableBinding) elementType; char[] variableName = typeVariable.sourceName(); if (dims == 0) return new SingleTypeReference(variableName, this.pos); else//from w w w . ja v a 2 s . c om return new ArrayTypeReference(variableName, dims, this.pos); } else if (makeGeneric && elementType.isParameterizedType()) { // this branch currently cannot handle references of this shape: Outer<T>.Inner // should that be needed at some point the following variant might do: /* ParameterizedTypeBinding paramType = (ParameterizedTypeBinding)elementType; char[][] compoundName = paramType.compoundName; char[]tokenString = CharOperation.concatWith(compoundName, '$'); compoundName = CharOperation.splitOn('$', tokenString); TypeReference[][] arguments = new TypeReference[compoundName.length][]; int argPos = compoundName.length-1; boolean haveArguments = false; do { TypeBinding[] argumentTypes = paramType.arguments; if (argumentTypes != null) { haveArguments = true; TypeReference[] currentArgs = new TypeReference[argumentTypes.length]; arguments[argPos] = currentArgs; for (int i = 0; i < argumentTypes.length; i++) { currentArgs[i] = typeReference(argumentTypes[i]); } } ReferenceBinding enclosing = paramType.enclosingType(); argPos--; if (enclosing instanceof ParameterizedTypeBinding) paramType = (ParameterizedTypeBinding) enclosing; else break; } while (argPos >= 0); if (haveArguments) { long[] poss = new long[compoundName.length]; Arrays.fill(poss, this.pos); return new ParameterizedQualifiedTypeReference(compoundName, arguments, dims, poss); } */ ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) elementType; TypeBinding[] argumentTypes = paramType.arguments; if (argumentTypes != null) { char[][] compoundName = paramType.compoundName; char[] tokenString = CharOperation.concatWith(compoundName, '$'); compoundName = CharOperation.splitOn('$', tokenString); TypeReference[][] arguments = new TypeReference[compoundName.length][]; TypeReference[] lastArgs = new TypeReference[argumentTypes.length]; arguments[compoundName.length - 1] = lastArgs; for (int i = 0; i < argumentTypes.length; i++) { lastArgs[i] = typeReference(argumentTypes[i]); } long[] poss = new long[argumentTypes.length]; Arrays.fill(poss, this.pos); return new ParameterizedQualifiedTypeReference(compoundName, arguments, dims, poss); } } else if (elementType.isWildcard()) { WildcardBinding wildcard = (WildcardBinding) elementType; Wildcard result = new Wildcard(wildcard.boundKind); result.sourceStart = this.sourceStart; result.sourceEnd = this.sourceEnd; if (wildcard.bound != null) result.bound = typeReference(wildcard.bound); // Note(SH): I don't see dims to be relevant here, OK? return result; } // from this point: not generic: char[] typeName = "void".toCharArray(); //$NON-NLS-1$ char[][] qname = null; TypeAnchorReference anchorRef = null; if (elementType instanceof BaseTypeBinding) { typeName = ((BaseTypeBinding) elementType).simpleName; } else if (elementType instanceof ReferenceBinding) { ReferenceBinding referenceBinding = (ReferenceBinding) elementType; qname = TypeAnalyzer.compoundNameOfReferenceType(referenceBinding, true, false); if (referenceBinding instanceof DependentTypeBinding && ((DependentTypeBinding) referenceBinding).hasExplicitAnchor()) { DependentTypeBinding depBind = (DependentTypeBinding) referenceBinding; anchorRef = typeAnchorReference(depBind.getAnchor()); typeName = referenceBinding.internalName(); qname = null; } } char[] sname; if ((qname != null) && (qname.length == 1)) { sname = qname[0]; // use this qname = null; // not this } else { sname = typeName; } long[] poss = null; if (qname != null) { poss = new long[qname.length]; Arrays.fill(poss, this.pos); } if (anchorRef == null) { if (dims == 0) { if (qname == null) return new SingleTypeReference(sname, this.pos); else return new QualifiedTypeReference(qname, poss); } else { if (qname == null) return new ArrayTypeReference(sname, dims, this.pos); else { return new ArrayQualifiedTypeReference(qname, dims, poss); } } } else { TypeReference[] typeReferences = new TypeReference[] { anchorRef }; assert qname == null; return new ParameterizedSingleTypeReference(sname, typeReferences, dims, this.pos); } }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.TSuperHelper.java
License:Open Source License
public static boolean isMarkerInterface(TypeBinding type) { if (type.isWildcard()) // wildcards don't even have a name! return false; if (type instanceof ReferenceBinding && type.isValidBinding()) return OTNameUtils.isTSuperMarkerInterface(((ReferenceBinding) type).internalName()); return false; }