List of usage examples for org.eclipse.jdt.internal.compiler.ast Wildcard UNBOUND
int UNBOUND
To view the source code for org.eclipse.jdt.internal.compiler.ast Wildcard UNBOUND.
Click Source Link
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 2 s . 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 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; }//w w w .ja v a 2s . co m // 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:lombok.eclipse.handlers.ast.EclipseASTMaker.java
License:Open Source License
@Override public ASTNode visitWildcard(final lombok.ast.Wildcard node, final Void p) { int kind = Wildcard.UNBOUND; if (node.getBound() != null) { switch (node.getBound()) { case SUPER: kind = Wildcard.SUPER;//from w ww. j av a 2 s . c om break; default: case EXTENDS: kind = Wildcard.EXTENDS; } } final Wildcard wildcard = new Wildcard(kind); setGeneratedByAndCopyPos(wildcard, source, posHintOf(node)); wildcard.bound = build(node.getType()); return wildcard; }
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;/* w ww.j a va 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:lombok.eclipse.handlers.HandleEqualsAndHashCode.java
License:Open Source License
public MethodDeclaration createEquals(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source, FieldAccess fieldAccess, boolean needsCanEqual, List<Annotation> onParam) { int pS = source.sourceStart; int pE = source.sourceEnd; long p = (long) pS << 32 | pE; TypeDeclaration typeDecl = (TypeDeclaration) type.get(); MethodDeclaration method = new MethodDeclaration( ((CompilationUnitDeclaration) type.top().get()).compilationResult); setGeneratedBy(method, source);// w ww . j a v a 2s . c o m method.modifiers = toEclipseModifier(AccessLevel.PUBLIC); method.returnType = TypeReference.baseTypeReference(TypeIds.T_boolean, 0); method.returnType.sourceStart = pS; method.returnType.sourceEnd = pE; setGeneratedBy(method.returnType, source); method.annotations = new Annotation[] { makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source) }; method.selector = "equals".toCharArray(); method.thrownExceptions = null; method.typeParameters = null; method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart; method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; TypeReference objectRef = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, new long[] { p, p, p }); setGeneratedBy(objectRef, source); method.arguments = new Argument[] { new Argument(new char[] { 'o' }, 0, objectRef, Modifier.FINAL) }; method.arguments[0].sourceStart = pS; method.arguments[0].sourceEnd = pE; if (!onParam.isEmpty()) method.arguments[0].annotations = onParam.toArray(new Annotation[0]); setGeneratedBy(method.arguments[0], source); List<Statement> statements = new ArrayList<Statement>(); /* if (o == this) return true; */ { SingleNameReference oRef = new SingleNameReference(new char[] { 'o' }, p); setGeneratedBy(oRef, source); ThisReference thisRef = new ThisReference(pS, pE); setGeneratedBy(thisRef, source); EqualExpression otherEqualsThis = new EqualExpression(oRef, thisRef, OperatorIds.EQUAL_EQUAL); setGeneratedBy(otherEqualsThis, source); TrueLiteral trueLiteral = new TrueLiteral(pS, pE); setGeneratedBy(trueLiteral, source); ReturnStatement returnTrue = new ReturnStatement(trueLiteral, pS, pE); setGeneratedBy(returnTrue, source); IfStatement ifOtherEqualsThis = new IfStatement(otherEqualsThis, returnTrue, pS, pE); setGeneratedBy(ifOtherEqualsThis, source); statements.add(ifOtherEqualsThis); } /* if (!(o instanceof Outer.Inner.MyType) return false; */ { SingleNameReference oRef = new SingleNameReference(new char[] { 'o' }, p); setGeneratedBy(oRef, source); TypeReference typeReference = createTypeReference(type, p); setGeneratedBy(typeReference, source); InstanceOfExpression instanceOf = new InstanceOfExpression(oRef, typeReference); instanceOf.sourceStart = pS; instanceOf.sourceEnd = pE; setGeneratedBy(instanceOf, source); Expression notInstanceOf = new UnaryExpression(instanceOf, OperatorIds.NOT); setGeneratedBy(notInstanceOf, source); FalseLiteral falseLiteral = new FalseLiteral(pS, pE); setGeneratedBy(falseLiteral, source); ReturnStatement returnFalse = new ReturnStatement(falseLiteral, pS, pE); setGeneratedBy(returnFalse, source); IfStatement ifNotInstanceOf = new IfStatement(notInstanceOf, returnFalse, pS, pE); setGeneratedBy(ifNotInstanceOf, source); statements.add(ifNotInstanceOf); } char[] otherName = "other".toCharArray(); /* MyType<?> other = (MyType<?>) o; */ { if (!fields.isEmpty() || needsCanEqual) { LocalDeclaration other = new LocalDeclaration(otherName, pS, pE); other.modifiers |= ClassFileConstants.AccFinal; setGeneratedBy(other, source); char[] typeName = typeDecl.name; TypeReference targetType; if (typeDecl.typeParameters == null || typeDecl.typeParameters.length == 0) { targetType = new SingleTypeReference(typeName, p); setGeneratedBy(targetType, source); other.type = new SingleTypeReference(typeName, p); setGeneratedBy(other.type, source); } else { TypeReference[] typeArgs = new TypeReference[typeDecl.typeParameters.length]; for (int i = 0; i < typeArgs.length; i++) { typeArgs[i] = new Wildcard(Wildcard.UNBOUND); typeArgs[i].sourceStart = pS; typeArgs[i].sourceEnd = pE; setGeneratedBy(typeArgs[i], source); } targetType = new ParameterizedSingleTypeReference(typeName, typeArgs, 0, p); setGeneratedBy(targetType, source); other.type = new ParameterizedSingleTypeReference(typeName, copyTypes(typeArgs, source), 0, p); setGeneratedBy(other.type, source); } NameReference oRef = new SingleNameReference(new char[] { 'o' }, p); setGeneratedBy(oRef, source); other.initialization = makeCastExpression(oRef, targetType, source); statements.add(other); } } /* if (!other.canEqual((java.lang.Object) this)) return false; */ { if (needsCanEqual) { MessageSend otherCanEqual = new MessageSend(); otherCanEqual.sourceStart = pS; otherCanEqual.sourceEnd = pE; setGeneratedBy(otherCanEqual, source); otherCanEqual.receiver = new SingleNameReference(otherName, p); setGeneratedBy(otherCanEqual.receiver, source); otherCanEqual.selector = "canEqual".toCharArray(); ThisReference thisReference = new ThisReference(pS, pE); setGeneratedBy(thisReference, source); CastExpression castThisRef = makeCastExpression(thisReference, generateQualifiedTypeRef(source, TypeConstants.JAVA_LANG_OBJECT), source); castThisRef.sourceStart = pS; castThisRef.sourceEnd = pE; otherCanEqual.arguments = new Expression[] { castThisRef }; Expression notOtherCanEqual = new UnaryExpression(otherCanEqual, OperatorIds.NOT); setGeneratedBy(notOtherCanEqual, source); FalseLiteral falseLiteral = new FalseLiteral(pS, pE); setGeneratedBy(falseLiteral, source); ReturnStatement returnFalse = new ReturnStatement(falseLiteral, pS, pE); setGeneratedBy(returnFalse, source); IfStatement ifNotCanEqual = new IfStatement(notOtherCanEqual, returnFalse, pS, pE); setGeneratedBy(ifNotCanEqual, source); statements.add(ifNotCanEqual); } } /* if (!super.equals(o)) return false; */ if (callSuper) { MessageSend callToSuper = new MessageSend(); callToSuper.sourceStart = pS; callToSuper.sourceEnd = pE; setGeneratedBy(callToSuper, source); callToSuper.receiver = new SuperReference(pS, pE); setGeneratedBy(callToSuper.receiver, source); callToSuper.selector = "equals".toCharArray(); SingleNameReference oRef = new SingleNameReference(new char[] { 'o' }, p); setGeneratedBy(oRef, source); callToSuper.arguments = new Expression[] { oRef }; Expression superNotEqual = new UnaryExpression(callToSuper, OperatorIds.NOT); setGeneratedBy(superNotEqual, source); FalseLiteral falseLiteral = new FalseLiteral(pS, pE); setGeneratedBy(falseLiteral, source); ReturnStatement returnFalse = new ReturnStatement(falseLiteral, pS, pE); setGeneratedBy(returnFalse, source); IfStatement ifSuperEquals = new IfStatement(superNotEqual, returnFalse, pS, pE); setGeneratedBy(ifSuperEquals, source); statements.add(ifSuperEquals); } for (EclipseNode field : fields) { TypeReference fType = getFieldType(field, fieldAccess); char[] token = fType.getLastToken(); Expression thisFieldAccessor = createFieldAccessor(field, fieldAccess, source); Expression otherFieldAccessor = createFieldAccessor(field, fieldAccess, source, otherName); if (fType.dimensions() == 0 && token != null) { if (Arrays.equals(TypeConstants.FLOAT, token)) { statements.add(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, "Float".toCharArray(), source)); } else if (Arrays.equals(TypeConstants.DOUBLE, token)) { statements.add(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, "Double".toCharArray(), source)); } else if (BUILT_IN_TYPES.contains(new String(token))) { EqualExpression fieldsNotEqual = new EqualExpression(thisFieldAccessor, otherFieldAccessor, OperatorIds.NOT_EQUAL); setGeneratedBy(fieldsNotEqual, source); FalseLiteral falseLiteral = new FalseLiteral(pS, pE); setGeneratedBy(falseLiteral, source); ReturnStatement returnStatement = new ReturnStatement(falseLiteral, pS, pE); setGeneratedBy(returnStatement, source); IfStatement ifStatement = new IfStatement(fieldsNotEqual, returnStatement, pS, pE); setGeneratedBy(ifStatement, source); statements.add(ifStatement); } else /* objects */ { /* final java.lang.Object this$fieldName = this.fieldName; */ /* final java.lang.Object other$fieldName = other.fieldName; */ /* if (this$fieldName == null ? other$fieldName != null : !this$fieldName.equals(other$fieldName)) return false;; */ char[] thisDollarFieldName = ("this$" + field.getName()).toCharArray(); char[] otherDollarFieldName = ("other$" + field.getName()).toCharArray(); statements.add(createLocalDeclaration(source, thisDollarFieldName, generateQualifiedTypeRef(source, TypeConstants.JAVA_LANG_OBJECT), thisFieldAccessor)); statements.add(createLocalDeclaration(source, otherDollarFieldName, generateQualifiedTypeRef(source, TypeConstants.JAVA_LANG_OBJECT), otherFieldAccessor)); SingleNameReference this1 = new SingleNameReference(thisDollarFieldName, p); setGeneratedBy(this1, source); SingleNameReference this2 = new SingleNameReference(thisDollarFieldName, p); setGeneratedBy(this2, source); SingleNameReference other1 = new SingleNameReference(otherDollarFieldName, p); setGeneratedBy(other1, source); SingleNameReference other2 = new SingleNameReference(otherDollarFieldName, p); setGeneratedBy(other2, source); NullLiteral nullLiteral = new NullLiteral(pS, pE); setGeneratedBy(nullLiteral, source); EqualExpression fieldIsNull = new EqualExpression(this1, nullLiteral, OperatorIds.EQUAL_EQUAL); nullLiteral = new NullLiteral(pS, pE); setGeneratedBy(nullLiteral, source); EqualExpression otherFieldIsntNull = new EqualExpression(other1, nullLiteral, OperatorIds.NOT_EQUAL); MessageSend equalsCall = new MessageSend(); equalsCall.sourceStart = pS; equalsCall.sourceEnd = pE; setGeneratedBy(equalsCall, source); equalsCall.receiver = this2; equalsCall.selector = "equals".toCharArray(); equalsCall.arguments = new Expression[] { other2 }; UnaryExpression fieldsNotEqual = new UnaryExpression(equalsCall, OperatorIds.NOT); fieldsNotEqual.sourceStart = pS; fieldsNotEqual.sourceEnd = pE; setGeneratedBy(fieldsNotEqual, source); ConditionalExpression fullEquals = new ConditionalExpression(fieldIsNull, otherFieldIsntNull, fieldsNotEqual); fullEquals.sourceStart = pS; fullEquals.sourceEnd = pE; setGeneratedBy(fullEquals, source); FalseLiteral falseLiteral = new FalseLiteral(pS, pE); setGeneratedBy(falseLiteral, source); ReturnStatement returnStatement = new ReturnStatement(falseLiteral, pS, pE); setGeneratedBy(returnStatement, source); IfStatement ifStatement = new IfStatement(fullEquals, returnStatement, pS, pE); setGeneratedBy(ifStatement, source); statements.add(ifStatement); } } else if (fType.dimensions() > 0 && token != null) { MessageSend arraysEqualCall = new MessageSend(); arraysEqualCall.sourceStart = pS; arraysEqualCall.sourceEnd = pE; setGeneratedBy(arraysEqualCall, source); arraysEqualCall.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray()); if (fType.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(token))) { arraysEqualCall.selector = "deepEquals".toCharArray(); } else { arraysEqualCall.selector = "equals".toCharArray(); } arraysEqualCall.arguments = new Expression[] { thisFieldAccessor, otherFieldAccessor }; UnaryExpression arraysNotEqual = new UnaryExpression(arraysEqualCall, OperatorIds.NOT); arraysNotEqual.sourceStart = pS; arraysNotEqual.sourceEnd = pE; setGeneratedBy(arraysNotEqual, source); FalseLiteral falseLiteral = new FalseLiteral(pS, pE); setGeneratedBy(falseLiteral, source); ReturnStatement returnStatement = new ReturnStatement(falseLiteral, pS, pE); setGeneratedBy(returnStatement, source); IfStatement ifStatement = new IfStatement(arraysNotEqual, returnStatement, pS, pE); setGeneratedBy(ifStatement, source); statements.add(ifStatement); } } /* return true; */ { TrueLiteral trueLiteral = new TrueLiteral(pS, pE); setGeneratedBy(trueLiteral, source); ReturnStatement returnStatement = new ReturnStatement(trueLiteral, pS, pE); setGeneratedBy(returnStatement, source); statements.add(returnStatement); } method.statements = statements.toArray(new Statement[statements.size()]); return method; }
From source file:lombok.eclipse.handlers.HandleSuperBuilder.java
License:Open Source License
/** * Generates a constructor that has a builder as the only parameter. * The values from the builder are used to initialize the fields of new instances. * * @param typeNode//w w w. java 2s .com * the type (with the {@code @Builder} annotation) for which a * constructor should be generated. * @param typeParams * @param builderFields a list of fields in the builder which should be assigned to new instances. * @param source the annotation (used for setting source code locations for the generated code). * @param callBuilderBasedSuperConstructor * If {@code true}, the constructor will explicitly call a super * constructor with the builder as argument. Requires * {@code builderClassAsParameter != null}. */ private void generateBuilderBasedConstructor(EclipseNode typeNode, TypeParameter[] typeParams, List<BuilderFieldData> builderFields, EclipseNode sourceNode, String builderClassName, boolean callBuilderBasedSuperConstructor) { ASTNode source = sourceNode.get(); TypeDeclaration typeDeclaration = ((TypeDeclaration) typeNode.get()); long p = (long) source.sourceStart << 32 | source.sourceEnd; ConstructorDeclaration constructor = new ConstructorDeclaration( ((CompilationUnitDeclaration) typeNode.top().get()).compilationResult); constructor.modifiers = toEclipseModifier(AccessLevel.PROTECTED); constructor.selector = typeDeclaration.name; if (callBuilderBasedSuperConstructor) { constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.Super); constructor.constructorCall.arguments = new Expression[] { new SingleNameReference(BUILDER_VARIABLE_NAME, p) }; } else { constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper); } constructor.constructorCall.sourceStart = source.sourceStart; constructor.constructorCall.sourceEnd = source.sourceEnd; constructor.thrownExceptions = null; constructor.typeParameters = null; constructor.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; constructor.bodyStart = constructor.declarationSourceStart = constructor.sourceStart = source.sourceStart; constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = source.sourceEnd; TypeReference[] wildcards = new TypeReference[] { new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND) }; TypeReference builderType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(), mergeToTypeReferences(typeParams, wildcards), 0, p); constructor.arguments = new Argument[] { new Argument(BUILDER_VARIABLE_NAME, p, builderType, Modifier.FINAL) }; List<Statement> statements = new ArrayList<Statement>(); for (BuilderFieldData fieldNode : builderFields) { char[] fieldName = removePrefixFromField(fieldNode.originalFieldNode); FieldReference fieldInThis = new FieldReference(fieldNode.rawName, p); int s = (int) (p >> 32); int e = (int) p; fieldInThis.receiver = new ThisReference(s, e); Expression assignmentExpr; if (fieldNode.singularData != null && fieldNode.singularData.getSingularizer() != null) { fieldNode.singularData.getSingularizer().appendBuildCode(fieldNode.singularData, typeNode, statements, fieldNode.name, BUILDER_VARIABLE_NAME_STRING); assignmentExpr = new SingleNameReference(fieldNode.name, p); } else { char[][] variableInBuilder = new char[][] { BUILDER_VARIABLE_NAME, fieldName }; long[] positions = new long[] { p, p }; assignmentExpr = new QualifiedNameReference(variableInBuilder, positions, s, e); } Statement assignment = new Assignment(fieldInThis, assignmentExpr, (int) p); // In case of @Builder.Default, set the value to the default if it was NOT set in the builder. if (fieldNode.nameOfSetFlag != null) { char[][] setVariableInBuilder = new char[][] { BUILDER_VARIABLE_NAME, fieldNode.nameOfSetFlag }; long[] positions = new long[] { p, p }; QualifiedNameReference setVariableInBuilderRef = new QualifiedNameReference(setVariableInBuilder, positions, s, e); MessageSend defaultMethodCall = new MessageSend(); defaultMethodCall.sourceStart = source.sourceStart; defaultMethodCall.sourceEnd = source.sourceEnd; defaultMethodCall.receiver = new SingleNameReference(((TypeDeclaration) typeNode.get()).name, 0L); defaultMethodCall.selector = fieldNode.nameOfDefaultProvider; defaultMethodCall.typeArguments = typeParameterNames( ((TypeDeclaration) typeNode.get()).typeParameters); Statement defaultAssignment = new Assignment(fieldInThis, defaultMethodCall, (int) p); IfStatement ifBlockForDefault = new IfStatement(setVariableInBuilderRef, assignment, defaultAssignment, s, e); statements.add(ifBlockForDefault); } else { statements.add(assignment); } if (hasNonNullAnnotations(fieldNode.originalFieldNode)) { Statement nullCheck = generateNullCheck((FieldDeclaration) fieldNode.originalFieldNode.get(), sourceNode); if (nullCheck != null) statements.add(nullCheck); } } constructor.statements = statements.isEmpty() ? null : statements.toArray(new Statement[0]); constructor.traverse(new SetGeneratedByVisitor(source), typeDeclaration.scope); injectMethod(typeNode, constructor); }
From source file:lombok.eclipse.handlers.HandleSuperBuilder.java
License:Open Source License
private MethodDeclaration generateBuilderMethod(String builderMethodName, String builderClassName, String builderImplClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long) pS << 32 | pE; MethodDeclaration out = new MethodDeclaration( ((CompilationUnitDeclaration) type.top().get()).compilationResult); out.selector = builderMethodName.toCharArray(); out.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic; out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; // Add type params if there are any. if (typeParams != null && typeParams.length > 0) out.typeParameters = copyTypeParams(typeParams, source); TypeReference[] wildcards = new TypeReference[] { new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND) }; out.returnType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(), mergeToTypeReferences(typeParams, wildcards), 0, p); AllocationExpression invoke = new AllocationExpression(); invoke.type = namePlusTypeParamsToTypeReference(builderImplClassName.toCharArray(), typeParams, p); out.statements = new Statement[] { new ReturnStatement(invoke, pS, pE) }; out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope); return out;//from ww w.j a v a2s. c o m }
From source file:lombok.eclipse.handlers.HandleSuperBuilder.java
License:Open Source License
/** * Generates a <code>toBuilder()</code> method in the annotated class that looks like this: * <pre>/*w w w .ja v a 2s . c om*/ * public ParentBuilder<?, ?> toBuilder() { * return new <i>Foobar</i>BuilderImpl().$fillValuesFrom(this); * } * </pre> */ private MethodDeclaration generateToBuilderMethod(String builderClassName, String builderImplClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long) pS << 32 | pE; MethodDeclaration out = new MethodDeclaration( ((CompilationUnitDeclaration) type.top().get()).compilationResult); out.selector = TO_BUILDER_METHOD_NAME; out.modifiers = ClassFileConstants.AccPublic; out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; TypeReference[] wildcards = new TypeReference[] { new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND) }; out.returnType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(), mergeToTypeReferences(typeParams, wildcards), 0, p); AllocationExpression newClass = new AllocationExpression(); newClass.type = namePlusTypeParamsToTypeReference(builderImplClassName.toCharArray(), typeParams, p); MessageSend invokeFillMethod = new MessageSend(); invokeFillMethod.receiver = newClass; invokeFillMethod.selector = FILL_VALUES_METHOD_NAME; invokeFillMethod.arguments = new Expression[] { new ThisReference(0, 0) }; out.statements = new Statement[] { new ReturnStatement(invokeFillMethod, pS, pE) }; out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope); return out; }
From source file:lombok.eclipse.handlers.HandleSuperBuilder.java
License:Open Source License
/** * Generates a <code>$fillValuesFromInstanceIntoBuilder()</code> method in * the builder implementation class that copies all fields from the instance * to the builder. It looks like this://from w ww .ja v a2 s . c o m * * <pre> * protected B $fillValuesFromInstanceIntoBuilder(Foobar instance, FoobarBuilder<?, ?> b) { * b.field(instance.field); * } * </pre> */ private MethodDeclaration generateStaticFillValuesMethod(EclipseNode tdParent, String builderClassName, TypeParameter[] typeParams, java.util.List<BuilderFieldData> builderFields, ASTNode source) { MethodDeclaration out = new MethodDeclaration( ((CompilationUnitDeclaration) tdParent.top().get()).compilationResult); out.selector = FILL_VALUES_STATIC_METHOD_NAME; out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; out.modifiers = ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic; out.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0); TypeReference[] wildcards = new TypeReference[] { new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND) }; TypeReference builderType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(), mergeToTypeReferences(typeParams, wildcards), 0, 0); Argument builderArgument = new Argument(BUILDER_VARIABLE_NAME, 0, builderType, Modifier.FINAL); TypeReference parentArgument = createTypeReferenceWithTypeParameters(tdParent.getName(), typeParams); out.arguments = new Argument[] { new Argument(INSTANCE_VARIABLE_NAME, 0, parentArgument, Modifier.FINAL), builderArgument }; // Add type params if there are any. if (typeParams.length > 0) out.typeParameters = copyTypeParams(typeParams, source); List<Statement> body = new ArrayList<Statement>(); // Call the builder's setter methods to fill the values from the instance. for (BuilderFieldData bfd : builderFields) { MessageSend exec = createSetterCallWithInstanceValue(bfd, tdParent, source); body.add(exec); } out.statements = body.isEmpty() ? null : body.toArray(new Statement[0]); return out; }
From source file:org.codehaus.jdt.groovy.internal.compiler.ast.GroovyCompilationUnitDeclaration.java
License:Open Source License
private TypeReference createTypeReferenceForClassNode(GenericsType genericsType) { if (genericsType.isWildcard()) { ClassNode[] bounds = genericsType.getUpperBounds(); if (bounds != null) { // FIXASC other bounds? // positions example: (29>31)Set<(33>54)? extends (43>54)Serializable> TypeReference boundReference = createTypeReferenceForClassNode(bounds[0]); Wildcard wildcard = new Wildcard(Wildcard.EXTENDS); wildcard.sourceStart = genericsType.getStart(); wildcard.sourceEnd = boundReference.sourceEnd(); wildcard.bound = boundReference; return wildcard; } else if (genericsType.getLowerBound() != null) { // positions example: (67>69)Set<(71>84)? super (79>84)Number> TypeReference boundReference = createTypeReferenceForClassNode(genericsType.getLowerBound()); Wildcard wildcard = new Wildcard(Wildcard.SUPER); wildcard.sourceStart = genericsType.getStart(); wildcard.sourceEnd = boundReference.sourceEnd(); wildcard.bound = boundReference; return wildcard; } else {// w ww . jav a 2 s .c o m Wildcard w = new Wildcard(Wildcard.UNBOUND); w.sourceStart = genericsType.getStart(); w.sourceEnd = genericsType.getStart(); return w; } // FIXASC what does the check on this next really line mean? } else if (!genericsType.getType().isGenericsPlaceHolder()) { TypeReference typeReference = createTypeReferenceForClassNode(genericsType.getType()); return typeReference; } else { // this means it is a placeholder. As an example, if the reference is to 'List' // then the genericsType info may include a placeholder for the type variable (as the user // didn't fill it in as anything) and so for this example the genericsType is 'E extends java.lang.Object' // I don't think we need a type reference for this as the type references we are constructed // here are representative of what the user did in the source, not the resolved result of that. // throw new GroovyEclipseBug(); return null; } }