List of usage examples for org.eclipse.jdt.internal.compiler.ast MethodDeclaration isStatic
public boolean isStatic()
From source file:lombok.eclipse.handlers.HandleBuilder.java
License:Open Source License
@Override public void handle(AnnotationValues<Builder> annotation, Annotation ast, EclipseNode annotationNode) { long p = (long) ast.sourceStart << 32 | ast.sourceEnd; Builder builderInstance = annotation.getInstance(); // These exist just to support the 'old' lombok.experimental.Builder, which had these properties. lombok.Builder no longer has them. boolean fluent = toBoolean(annotation.getActualExpression("fluent"), true); boolean chain = toBoolean(annotation.getActualExpression("chain"), true); String builderMethodName = builderInstance.builderMethodName(); String buildMethodName = builderInstance.buildMethodName(); String builderClassName = builderInstance.builderClassName(); String toBuilderMethodName = "toBuilder"; boolean toBuilder = builderInstance.toBuilder(); List<char[]> typeArgsForToBuilder = null; if (builderMethodName == null) builderMethodName = "builder"; if (buildMethodName == null) builderMethodName = "build"; if (builderClassName == null) builderClassName = ""; if (!checkName("builderMethodName", builderMethodName, annotationNode)) return;//from w w w. j av a 2 s . c o m if (!checkName("buildMethodName", buildMethodName, annotationNode)) return; if (!builderClassName.isEmpty()) { if (!checkName("builderClassName", builderClassName, annotationNode)) return; } EclipseNode parent = annotationNode.up(); List<BuilderFieldData> builderFields = new ArrayList<BuilderFieldData>(); TypeReference returnType; TypeParameter[] typeParams; TypeReference[] thrownExceptions; char[] nameOfStaticBuilderMethod; EclipseNode tdParent; EclipseNode fillParametersFrom = parent.get() instanceof AbstractMethodDeclaration ? parent : null; boolean addCleaning = false; if (parent.get() instanceof TypeDeclaration) { tdParent = parent; TypeDeclaration td = (TypeDeclaration) tdParent.get(); List<EclipseNode> allFields = new ArrayList<EclipseNode>(); @SuppressWarnings("deprecation") boolean valuePresent = (hasAnnotation(lombok.Value.class, parent) || hasAnnotation(lombok.experimental.Value.class, parent)); for (EclipseNode fieldNode : HandleConstructor.findAllFields(tdParent)) { FieldDeclaration fd = (FieldDeclaration) fieldNode.get(); // final fields with an initializer cannot be written to, so they can't be 'builderized'. Unfortunately presence of @Value makes // non-final fields final, but @Value's handler hasn't done this yet, so we have to do this math ourselves. // Value will only skip making a field final if it has an explicit @NonFinal annotation, so we check for that. if (fd.initialization != null && valuePresent && !hasAnnotation(NonFinal.class, fieldNode)) continue; BuilderFieldData bfd = new BuilderFieldData(); bfd.rawName = fieldNode.getName().toCharArray(); bfd.name = removePrefixFromField(fieldNode); bfd.type = fd.type; bfd.singularData = getSingularData(fieldNode, ast); addObtainVia(bfd, fieldNode); builderFields.add(bfd); allFields.add(fieldNode); } new HandleConstructor().generateConstructor(tdParent, AccessLevel.PACKAGE, allFields, false, null, SkipIfConstructorExists.I_AM_BUILDER, null, Collections.<Annotation>emptyList(), annotationNode); returnType = namePlusTypeParamsToTypeReference(td.name, td.typeParameters, p); typeParams = td.typeParameters; thrownExceptions = null; nameOfStaticBuilderMethod = null; if (builderClassName.isEmpty()) builderClassName = new String(td.name) + "Builder"; } else if (parent.get() instanceof ConstructorDeclaration) { ConstructorDeclaration cd = (ConstructorDeclaration) parent.get(); if (cd.typeParameters != null && cd.typeParameters.length > 0) { annotationNode .addError("@Builder is not supported on constructors with constructor type parameters."); return; } tdParent = parent.up(); TypeDeclaration td = (TypeDeclaration) tdParent.get(); returnType = namePlusTypeParamsToTypeReference(td.name, td.typeParameters, p); typeParams = td.typeParameters; thrownExceptions = cd.thrownExceptions; nameOfStaticBuilderMethod = null; if (builderClassName.isEmpty()) builderClassName = new String(cd.selector) + "Builder"; } else if (parent.get() instanceof MethodDeclaration) { MethodDeclaration md = (MethodDeclaration) parent.get(); tdParent = parent.up(); if (!md.isStatic()) { annotationNode.addError("@Builder is only supported on types, constructors, and static methods."); return; } if (toBuilder) { final String TO_BUILDER_NOT_SUPPORTED = "@Builder(toBuilder=true) is only supported if you return your own type."; char[] token; char[][] pkg = null; if (md.returnType.dimensions() > 0) { annotationNode.addError(TO_BUILDER_NOT_SUPPORTED); return; } if (md.returnType instanceof SingleTypeReference) { token = ((SingleTypeReference) md.returnType).token; } else if (md.returnType instanceof QualifiedTypeReference) { pkg = ((QualifiedTypeReference) md.returnType).tokens; token = pkg[pkg.length]; char[][] pkg_ = new char[pkg.length - 1][]; System.arraycopy(pkg, 0, pkg_, 0, pkg_.length); pkg = pkg_; } else { annotationNode.addError(TO_BUILDER_NOT_SUPPORTED); return; } if (pkg != null && !equals(parent.getPackageDeclaration(), pkg)) { annotationNode.addError(TO_BUILDER_NOT_SUPPORTED); return; } if (tdParent == null || !equals(tdParent.getName(), token)) { annotationNode.addError(TO_BUILDER_NOT_SUPPORTED); return; } TypeParameter[] tpOnType = ((TypeDeclaration) tdParent.get()).typeParameters; TypeParameter[] tpOnMethod = md.typeParameters; TypeReference[][] tpOnRet_ = null; if (md.returnType instanceof ParameterizedSingleTypeReference) { tpOnRet_ = new TypeReference[1][]; tpOnRet_[0] = ((ParameterizedSingleTypeReference) md.returnType).typeArguments; } else if (md.returnType instanceof ParameterizedQualifiedTypeReference) { tpOnRet_ = ((ParameterizedQualifiedTypeReference) md.returnType).typeArguments; } if (tpOnRet_ != null) for (int i = 0; i < tpOnRet_.length - 1; i++) { if (tpOnRet_[i] != null && tpOnRet_[i].length > 0) { annotationNode.addError( "@Builder(toBuilder=true) is not supported if returning a type with generics applied to an intermediate."); return; } } TypeReference[] tpOnRet = tpOnRet_ == null ? null : tpOnRet_[tpOnRet_.length - 1]; typeArgsForToBuilder = new ArrayList<char[]>(); // Every typearg on this method needs to be found in the return type, but the reverse is not true. // We also need to 'map' them. if (tpOnMethod != null) for (TypeParameter onMethod : tpOnMethod) { int pos = -1; if (tpOnRet != null) for (int i = 0; i < tpOnRet.length; i++) { if (tpOnRet[i].getClass() != SingleTypeReference.class) continue; if (!Arrays.equals(((SingleTypeReference) tpOnRet[i]).token, onMethod.name)) continue; pos = i; } if (pos == -1 || tpOnType == null || tpOnType.length <= pos) { annotationNode.addError( "@Builder(toBuilder=true) requires that each type parameter on the static method is part of the typeargs of the return value. Type parameter " + new String(onMethod.name) + " is not part of the return type."); return; } typeArgsForToBuilder.add(tpOnType[pos].name); } } returnType = copyType(md.returnType, ast); typeParams = md.typeParameters; thrownExceptions = md.thrownExceptions; nameOfStaticBuilderMethod = md.selector; if (builderClassName.isEmpty()) { char[] token; if (md.returnType instanceof QualifiedTypeReference) { char[][] tokens = ((QualifiedTypeReference) md.returnType).tokens; token = tokens[tokens.length - 1]; } else if (md.returnType instanceof SingleTypeReference) { token = ((SingleTypeReference) md.returnType).token; if (!(md.returnType instanceof ParameterizedSingleTypeReference) && typeParams != null) { for (TypeParameter tp : typeParams) { if (Arrays.equals(tp.name, token)) { annotationNode.addError( "@Builder requires specifying 'builderClassName' if used on methods with a type parameter as return type."); return; } } } } else { annotationNode.addError( "Unexpected kind of return type on annotated method. Specify 'builderClassName' to solve this problem."); return; } if (Character.isLowerCase(token[0])) { char[] newToken = new char[token.length]; System.arraycopy(token, 1, newToken, 1, token.length - 1); newToken[0] = Character.toTitleCase(token[0]); token = newToken; } builderClassName = new String(token) + "Builder"; } } else { annotationNode.addError("@Builder is only supported on types, constructors, and static methods."); return; } if (fillParametersFrom != null) { for (EclipseNode param : fillParametersFrom.down()) { if (param.getKind() != Kind.ARGUMENT) continue; BuilderFieldData bfd = new BuilderFieldData(); Argument arg = (Argument) param.get(); bfd.rawName = arg.name; bfd.name = arg.name; bfd.type = arg.type; bfd.singularData = getSingularData(param, ast); addObtainVia(bfd, param); builderFields.add(bfd); } } EclipseNode builderType = findInnerClass(tdParent, builderClassName); if (builderType == null) { builderType = makeBuilderClass(tdParent, builderClassName, typeParams, ast); } else { sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderType, annotationNode); /* generate errors for @Singular BFDs that have one already defined node. */ { for (BuilderFieldData bfd : builderFields) { SingularData sd = bfd.singularData; if (sd == null) continue; EclipseSingularizer singularizer = sd.getSingularizer(); if (singularizer == null) continue; if (singularizer.checkForAlreadyExistingNodesAndGenerateError(builderType, sd)) { bfd.singularData = null; } } } } for (BuilderFieldData bfd : builderFields) { if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) { if (bfd.singularData.getSingularizer().requiresCleaning()) { addCleaning = true; break; } } if (bfd.obtainVia != null) { if (bfd.obtainVia.field().isEmpty() == bfd.obtainVia.method().isEmpty()) { bfd.obtainViaNode.addError( "The syntax is either @ObtainVia(field = \"fieldName\") or @ObtainVia(method = \"methodName\")."); return; } if (bfd.obtainVia.method().isEmpty() && bfd.obtainVia.isStatic()) { bfd.obtainViaNode .addError("@ObtainVia(isStatic = true) is not valid unless 'method' has been set."); return; } } } generateBuilderFields(builderType, builderFields, ast); if (addCleaning) { FieldDeclaration cleanDecl = new FieldDeclaration(CLEAN_FIELD_NAME, 0, -1); cleanDecl.declarationSourceEnd = -1; cleanDecl.modifiers = ClassFileConstants.AccPrivate; cleanDecl.type = TypeReference.baseTypeReference(TypeIds.T_boolean, 0); injectFieldAndMarkGenerated(builderType, cleanDecl); } if (constructorExists(builderType) == MemberExistsResult.NOT_EXISTS) { ConstructorDeclaration cd = HandleConstructor.createConstructor(AccessLevel.PACKAGE, builderType, Collections.<EclipseNode>emptyList(), false, null, annotationNode, Collections.<Annotation>emptyList()); if (cd != null) injectMethod(builderType, cd); } for (BuilderFieldData bfd : builderFields) { makeSetterMethodsForBuilder(builderType, bfd, annotationNode, fluent, chain); } if (methodExists(buildMethodName, builderType, -1) == MemberExistsResult.NOT_EXISTS) { MethodDeclaration md = generateBuildMethod(buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, addCleaning, ast); if (md != null) injectMethod(builderType, md); } if (methodExists("toString", builderType, 0) == MemberExistsResult.NOT_EXISTS) { List<EclipseNode> fieldNodes = new ArrayList<EclipseNode>(); for (BuilderFieldData bfd : builderFields) { fieldNodes.addAll(bfd.createdFields); } MethodDeclaration md = HandleToString.createToString(builderType, fieldNodes, true, false, ast, FieldAccess.ALWAYS_FIELD); if (md != null) injectMethod(builderType, md); } if (addCleaning) { MethodDeclaration cleanMethod = generateCleanMethod(builderFields, builderType, ast); if (cleanMethod != null) injectMethod(builderType, cleanMethod); } if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) { MethodDeclaration md = generateBuilderMethod(builderMethodName, builderClassName, tdParent, typeParams, ast); if (md != null) injectMethod(tdParent, md); } if (toBuilder) switch (methodExists(toBuilderMethodName, tdParent, 0)) { case EXISTS_BY_USER: annotationNode.addWarning("Not generating toBuilder() as it already exists."); break; case NOT_EXISTS: TypeParameter[] tps = typeParams; if (typeArgsForToBuilder != null) { tps = new TypeParameter[typeArgsForToBuilder.size()]; for (int i = 0; i < tps.length; i++) { tps[i] = new TypeParameter(); tps[i].name = typeArgsForToBuilder.get(i); } } MethodDeclaration md = generateToBuilderMethod(toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast); if (md != null) injectMethod(tdParent, md); } }
From source file:lombok.eclipse.handlers.HandleSynchronized.java
License:Open Source License
@Override public void preHandle(AnnotationValues<Synchronized> annotation, Annotation source, EclipseNode annotationNode) {//from w ww .ja v a2 s . c o m EclipseNode methodNode = annotationNode.up(); if (methodNode == null || methodNode.getKind() != Kind.METHOD || !(methodNode.get() instanceof MethodDeclaration)) return; MethodDeclaration method = (MethodDeclaration) methodNode.get(); if (method.isAbstract()) return; createLockField(annotation, annotationNode, method.isStatic(), false); }
From source file:lombok.eclipse.handlers.HandleSynchronized.java
License:Open Source License
@Override public void handle(AnnotationValues<Synchronized> annotation, Annotation source, EclipseNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.SYNCHRONIZED_FLAG_USAGE, "@Synchronized"); int p1 = source.sourceStart - 1; int p2 = source.sourceStart - 2; long pos = (((long) p1) << 32) | p2; EclipseNode methodNode = annotationNode.up(); if (methodNode == null || methodNode.getKind() != Kind.METHOD || !(methodNode.get() instanceof MethodDeclaration)) { annotationNode.addError("@Synchronized is legal only on methods."); return;//w ww . j a va 2 s. com } MethodDeclaration method = (MethodDeclaration) methodNode.get(); if (method.isAbstract()) { annotationNode.addError("@Synchronized is legal only on concrete methods."); return; } char[] lockName = createLockField(annotation, annotationNode, method.isStatic(), true); if (lockName == null) return; if (method.statements == null) return; Block block = new Block(0); setGeneratedBy(block, source); block.statements = method.statements; // Positions for in-method generated nodes are special block.sourceEnd = method.bodyEnd; block.sourceStart = method.bodyStart; Expression lockVariable; if (method.isStatic()) lockVariable = new QualifiedNameReference( new char[][] { methodNode.up().getName().toCharArray(), lockName }, new long[] { pos, pos }, p1, p2); else { lockVariable = new FieldReference(lockName, pos); ThisReference thisReference = new ThisReference(p1, p2); setGeneratedBy(thisReference, source); ((FieldReference) lockVariable).receiver = thisReference; } setGeneratedBy(lockVariable, source); method.statements = new Statement[] { new SynchronizedStatement(lockVariable, block, 0, 0) }; // Positions for in-method generated nodes are special method.statements[0].sourceEnd = method.bodyEnd; method.statements[0].sourceStart = method.bodyStart; setGeneratedBy(method.statements[0], source); methodNode.rebuild(); }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CalloutImplementor.java
License:Open Source License
private boolean transformCalloutMethodBodyResultMapping(ArrayList<Statement> statements, Expression resultExpr, CalloutMappingDeclaration calloutDecl, MethodDeclaration roleMethodDeclaration) { Expression resultMapper = null; ParameterMapping[] mappings = calloutDecl.mappings; boolean resultFound = false; int sStart = 0; int sEnd = 0; int resultStart = 0; int resultEnd = 0; for (int i = 0; i < mappings.length; i++) { if (!mappings[i].isUsedFor(calloutDecl.roleMethodSpec)) { if (CharOperation.equals(mappings[i].ident.token, IOTConstants.RESULT)) { if (resultFound) { roleMethodDeclaration.scope.problemReporter().duplicateParamMapping(mappings[i], IOTConstants.RESULT, /*isCallout*/true); return false; }/*from w w w.java2 s . c o m*/ resultMapper = mappings[i].expression; sStart = mappings[i].sourceStart; sEnd = mappings[i].sourceEnd; resultStart = mappings[i].ident.sourceStart; resultEnd = mappings[i].ident.sourceEnd; resultFound = true; } } } if (!resultFound) // CLOVER: never true in jacks suite { roleMethodDeclaration.scope.problemReporter().unmappedParameter(IOTConstants.RESULT, calloutDecl.roleMethodSpec, /*isCallout*/true); return false; } assert (resultMapper != null); assert (calloutDecl.baseMethodSpec.hasSignature); AstGenerator gen = new AstGenerator(resultStart, resultEnd); Statement callStatement = resultExpr; TypeBinding baseReturnType = calloutDecl.baseMethodSpec.returnType.resolvedType; if (baseReturnType != TypeBinding.VOID) { char[] localName = IOTConstants.RESULT; if (calloutDecl.baseMethodSpec instanceof FieldAccessSpec) localName = ((FieldAccessSpec) calloutDecl.baseMethodSpec).getFieldName(); calloutDecl.resultVar = gen.localVariable(localName, calloutDecl.baseMethodSpec.returnType.resolvedType, resultExpr); calloutDecl.resultVar.type.setBaseclassDecapsulation(DecapsulationState.REPORTED); callStatement = calloutDecl.resultVar; } gen.sourceStart = sStart; gen.sourceEnd = sEnd; statements.add(callStatement); if (!roleMethodDeclaration.isStatic()) { // for "base" in parameter mappings append: BaseType base = _OT$base; // do this _after_ the actual forwarding so that 'base' will not shadow anything (see 3.3.21-otjld-callout-to-field-anchored-type-3) FieldBinding baseField = TypeAnalyzer.findField(this._role.getBinding(), IOTConstants._OT_BASE, /*static*/false, false); if (baseField != null) // CLOVER: never false in jacks suite statements.add(gen.localVariable(IOTConstants.BASE, gen.baseclassReference(baseField.type), gen.singleNameReference(IOTConstants._OT_BASE))); } statements.add(gen.returnStatement(gen.potentialLift(null, // use default receiver resultMapper, calloutDecl.roleMethodSpec.returnType.resolvedType, false))); // no reversing required return true; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.PredicateGenerator.java
License:Open Source License
/** Find the next outer predicate to be invoked from `pred'. */ private static Expression getOuterPredicateCheck(MethodDeclaration pred, AstGenerator gen) { char[] predName = pred.selector; boolean isBasePredicate = CharOperation.prefixEquals(BASE_PREDICATE_PREFIX, pred.selector); ReferenceBinding site = pred.binding.declaringClass; ReferenceBinding currentType = site; while (true) { char[] outerName = null; TypeBinding[] outerParams = null; Expression[] outerArgs = null; int dollarCount = CharOperation.occurencesOf('$', predName); ReferenceBinding declaringClass = currentType; // assume this until we know better if (dollarCount == 4) { // binding predicate -> method predicate int dollarPos = CharOperation.lastIndexOf('$', predName); dollarPos = CharOperation.lastIndexOf('$', predName, 0, dollarPos - 1); outerName = CharOperation.subarray(predName, 0, dollarPos); outerParams = getArgTypesFromBindingPredicate(pred); outerArgs = makeArgExpressions(pred, outerParams.length, null, gen); } else {/*from w w w . j a v a2 s . c om*/ // next outer is a type level predicate: if (dollarCount >= 2) { // {binding,method} predicate -> role level predicate int dollarPos = CharOperation.lastIndexOf('$', predName); outerName = CharOperation.subarray(predName, 0, dollarPos); } else { // type level guard can travel outwards without changing the name: outerName = predName; declaringClass = currentType.enclosingType(); if (declaringClass == null || !declaringClass.isTeam()) return null; // travelling beyond outermost team } if (isBasePredicate) { // base arg only, drop binding/method args. outerParams = new TypeBinding[] { pred.binding.parameters[0] }; outerArgs = new Expression[] { gen.singleNameReference(BASE) }; } else { // non-base type-level guard: need no arg outerParams = Binding.NO_PARAMETERS; } } if (outerName == null) return null; MethodBinding outerMethod = TypeAnalyzer.findMethod(pred.scope, declaringClass, outerName, outerParams); if (outerMethod.isValidBinding()) return gen.messageSend(genOuterReceiver(outerMethod.declaringClass, site, pred.isStatic(), gen), outerMethod.selector, outerArgs); currentType = declaringClass; predName = outerName; } }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.PredicateGenerator.java
License:Open Source License
private static Expression getSuperPredicateCheck(MethodDeclaration pred, AstGenerator gen) { MethodBinding superMethod = null;//from w ww .j a va2s. c om ReferenceBinding thisType = pred.binding.declaringClass; ReferenceBinding superType = thisType.superclass(); while (superType != null) { superMethod = TypeAnalyzer.findMethod(pred.scope, superType, pred.selector, pred.binding.parameters); if (superMethod.isValidBinding()) { return gen.messageSend( pred.isStatic() ? gen.qualifiedNameReference(superType) : gen.superReference(), superMethod.selector, makeArgExpressions(pred, superMethod.parameters.length, null, gen)); } superType = superType.superclass(); } return null; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.TransformStatementsVisitor.java
License:Open Source License
/** May need to add arguments to a 'recursive' callin message send. */ @Override/*from ww w.j a va 2s. c o m*/ public boolean visit(MessageSend messageSend, BlockScope scope) { // scope is not reliable at this point due to unset scopes of block statements like "for" if (this._methodDeclarationStack.isEmpty()) return true; MethodDeclaration methodDecl = this._methodDeclarationStack.peek(); boolean isBaseCall = messageSend.receiver instanceof BaseReference; if (methodDecl.isCallin() && isRecursiveCall(methodDecl, messageSend, isBaseCall)) { // argument enhancing within callin methods: Expression[] args = messageSend.arguments; if (isBaseCall) { switch (this.weavingScheme) { case OTDRE: AstGenerator gen = new AstGenerator(messageSend); if (args == null || args.length == 0) { args = new Expression[] { gen.nullLiteral() }; } else { Expression[] boxedArgs = new Expression[args.length]; for (int i = 0; i < args.length; i++) { Argument argument = methodDecl.arguments[i + MethodSignatureEnhancer.getEnhancingArgLen(this.weavingScheme)]; TypeBinding argTypeBinding = argument.binding.type; if (argTypeBinding.isBaseType()) { boxedArgs[i] = gen.createBoxing(args[i], (BaseTypeBinding) argTypeBinding); continue; } else if (argument.type.isDeclaredLifting()) { LiftingTypeReference ltr = (LiftingTypeReference) argument.type; if (ltr.roleReference.resolvedType != null) { Expression teamThis = gen.qualifiedThisReference( methodDecl.binding.declaringClass.enclosingType()); boxedArgs[i] = new Lowering().lowerExpression(scope, args[i], ltr.roleReference.resolvedType, ltr.resolvedType, teamThis, true, true); continue; } // fall through } boxedArgs[i] = args[i]; } args = new Expression[] { gen.arrayAllocation( gen.qualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT), 1, boxedArgs) }; } break; case OTRE: if (args != null) { int len = args.length; if (methodDecl.isStatic()) // chop of premature isSuperAccess flag: System.arraycopy(args, 1, args = new Expression[len - 1], 0, len - 1); } } } messageSend.arguments = MethodSignatureEnhancer.enhanceArguments(args, messageSend.sourceEnd + 1, this.weavingScheme); messageSend.bits |= ASTNode.HasBeenTransformed; // mark only when args have really been enhanced } return true; }