Java Code Examples for lombok.javac.JavacNode#up()

The following examples show how to use lombok.javac.JavacNode#up() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: HandleSetter.java    From EasyMPermission with MIT License 6 votes vote down vote up
@Override public void handle(AnnotationValues<Setter> annotation, JCAnnotation ast, JavacNode annotationNode) {
	handleFlagUsage(annotationNode, ConfigurationKeys.SETTER_FLAG_USAGE, "@Setter");
	
	Collection<JavacNode> fields = annotationNode.upFromAnnotationToFields();
	deleteAnnotationIfNeccessary(annotationNode, Setter.class);
	deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
	JavacNode node = annotationNode.up();
	AccessLevel level = annotation.getInstance().value();
	
	if (level == AccessLevel.NONE || node == null) return;
	
	List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Setter(onMethod=", annotationNode);
	List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Setter(onParam=", annotationNode);
	
	switch (node.getKind()) {
	case FIELD:
		createSetterForFields(level, fields, annotationNode, true, onMethod, onParam);
		break;
	case TYPE:
		if (!onMethod.isEmpty()) annotationNode.addError("'onMethod' is not supported for @Setter on a type.");
		if (!onParam.isEmpty()) annotationNode.addError("'onParam' is not supported for @Setter on a type.");
		generateSetterForType(node, annotationNode, level, false);
		break;
	}
}
 
Example 2
Source File: HandleWither.java    From EasyMPermission with MIT License 6 votes vote down vote up
@Override public void handle(AnnotationValues<Wither> annotation, JCAnnotation ast, JavacNode annotationNode) {
	handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.WITHER_FLAG_USAGE, "@Wither");
	
	Collection<JavacNode> fields = annotationNode.upFromAnnotationToFields();
	deleteAnnotationIfNeccessary(annotationNode, Wither.class);
	deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
	JavacNode node = annotationNode.up();
	AccessLevel level = annotation.getInstance().value();
	
	if (level == AccessLevel.NONE || node == null) return;
	
	List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Wither(onMethod=", annotationNode);
	List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Wither(onParam=", annotationNode);
	
	switch (node.getKind()) {
	case FIELD:
		createWitherForFields(level, fields, annotationNode, true, onMethod, onParam);
		break;
	case TYPE:
		if (!onMethod.isEmpty()) annotationNode.addError("'onMethod' is not supported for @Wither on a type.");
		if (!onParam.isEmpty()) annotationNode.addError("'onParam' is not supported for @Wither on a type.");
		generateWitherForType(node, annotationNode, level, false);
		break;
	}
}
 
Example 3
Source File: HandleEqualsAndHashCode.java    From EasyMPermission with MIT License 6 votes vote down vote up
public JCExpression createTypeReference(JavacNode type) {
	java.util.List<String> list = new ArrayList<String>();
	list.add(type.getName());
	JavacNode tNode = type.up();
	while (tNode != null && tNode.getKind() == Kind.TYPE) {
		list.add(tNode.getName());
		tNode = tNode.up();
	}
	Collections.reverse(list);
	
	JavacTreeMaker maker = type.getTreeMaker();
	JCExpression chain = maker.Ident(type.toName(list.get(0)));
	
	for (int i = 1; i < list.size(); i++) {
		chain = maker.Select(chain, type.toName(list.get(i)));
	}
	
	return chain;
}
 
Example 4
Source File: HandleConstructor.java    From EasyMPermission with MIT License 6 votes vote down vote up
@Override public void handle(AnnotationValues<AllArgsConstructor> annotation, JCAnnotation ast, JavacNode annotationNode) {
	handleFlagUsage(annotationNode, ConfigurationKeys.ALL_ARGS_CONSTRUCTOR_FLAG_USAGE, "@AllArgsConstructor", ConfigurationKeys.ANY_CONSTRUCTOR_FLAG_USAGE, "any @xArgsConstructor");
	
	deleteAnnotationIfNeccessary(annotationNode, AllArgsConstructor.class);
	deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
	JavacNode typeNode = annotationNode.up();
	if (!checkLegality(typeNode, annotationNode, AllArgsConstructor.class.getSimpleName())) return;
	List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@AllArgsConstructor(onConstructor=", annotationNode);
	AllArgsConstructor ann = annotation.getInstance();
	AccessLevel level = ann.access();
	if (level == AccessLevel.NONE) return;
	String staticName = ann.staticName();
	Boolean suppressConstructorProperties = null;
	if (annotation.isExplicit("suppressConstructorProperties")) {
		@SuppressWarnings("deprecation")
		boolean suppress = ann.suppressConstructorProperties();
		suppressConstructorProperties = suppress;
	}
	new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findAllFields(typeNode), staticName, SkipIfConstructorExists.NO, suppressConstructorProperties, annotationNode);
}
 
Example 5
Source File: HandleTable.java    From sqlitemagic with Apache License 2.0 6 votes vote down vote up
@Override
public void handle(AnnotationValues<Table> annotation, JCTree.JCAnnotation ast, JavacNode annotationNode) {
  if (environment.isProcessingFailed()) {
    return;
  }
  Table tableInstance = annotation.getInstance();

  deleteAnnotationIfNeccessary(annotationNode, Table.class);
  deleteImportFromCompilationUnit(annotationNode, Table.class.getCanonicalName());

  JavacNode tableNode = annotationNode.up();
  final JavacTreeMaker maker = tableNode.getTreeMaker();

  final String tableName = getTableName(tableInstance, tableNode);
  final TableElement tableElement = environment.getTableElementByTableName(tableName);
  generateMagicMethods(maker, tableNode);
  generateMissingIdIfNeeded(maker, tableNode, tableElement);
}
 
Example 6
Source File: SingletonJavacHandler.java    From tutorials with MIT License 5 votes vote down vote up
@Override
public void handle(AnnotationValues<Singleton> annotation, JCTree.JCAnnotation ast, JavacNode annotationNode) {

    Context context = annotationNode.getContext();

    Javac8BasedLombokOptions options = Javac8BasedLombokOptions.replaceWithDelombokOptions(context);
    options.deleteLombokAnnotations();

    //remove annotation
    deleteAnnotationIfNeccessary(annotationNode, Singleton.class);
    //remove import
    deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");

    //private constructor
    JavacNode singletonClass = annotationNode.up();
    JavacTreeMaker singletonClassTreeMaker = singletonClass.getTreeMaker();

    addPrivateConstructor(singletonClass, singletonClassTreeMaker);

    //singleton holder
    JavacNode holderInnerClass = addInnerClass(singletonClass, singletonClassTreeMaker);

    //inject static field to this
    addInstanceVar(singletonClass, singletonClassTreeMaker, holderInnerClass);

    //add factory method
    addFactoryMethod(singletonClass, singletonClassTreeMaker, holderInnerClass);
}
 
Example 7
Source File: HandleConstructor.java    From EasyMPermission with MIT License 5 votes vote down vote up
@Override public void handle(AnnotationValues<NoArgsConstructor> annotation, JCAnnotation ast, JavacNode annotationNode) {
	handleFlagUsage(annotationNode, ConfigurationKeys.NO_ARGS_CONSTRUCTOR_FLAG_USAGE, "@NoArgsConstructor", ConfigurationKeys.ANY_CONSTRUCTOR_FLAG_USAGE, "any @xArgsConstructor");
	
	deleteAnnotationIfNeccessary(annotationNode, NoArgsConstructor.class);
	deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
	JavacNode typeNode = annotationNode.up();
	if (!checkLegality(typeNode, annotationNode, NoArgsConstructor.class.getSimpleName())) return;
	List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@NoArgsConstructor(onConstructor=", annotationNode);
	NoArgsConstructor ann = annotation.getInstance();
	AccessLevel level = ann.access();
	if (level == AccessLevel.NONE) return;
	String staticName = ann.staticName();
	List<JavacNode> fields = List.nil();
	new HandleConstructor().generateConstructor(typeNode, level, onConstructor, fields, staticName, SkipIfConstructorExists.NO, null, annotationNode);
}
 
Example 8
Source File: HandleGetter.java    From EasyMPermission with MIT License 5 votes vote down vote up
@Override public void handle(AnnotationValues<Getter> annotation, JCAnnotation ast, JavacNode annotationNode) {
	handleFlagUsage(annotationNode, ConfigurationKeys.GETTER_FLAG_USAGE, "@Getter");
	
	Collection<JavacNode> fields = annotationNode.upFromAnnotationToFields();
	deleteAnnotationIfNeccessary(annotationNode, Getter.class);
	deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
	JavacNode node = annotationNode.up();
	Getter annotationInstance = annotation.getInstance();
	AccessLevel level = annotationInstance.value();
	boolean lazy = annotationInstance.lazy();
	if (lazy) handleFlagUsage(annotationNode, ConfigurationKeys.GETTER_LAZY_FLAG_USAGE, "@Getter(lazy=true)");
	
	if (level == AccessLevel.NONE) {
		if (lazy) annotationNode.addWarning("'lazy' does not work with AccessLevel.NONE.");
		return;
	}
	
	if (node == null) return;
	
	List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Getter(onMethod=", annotationNode);
	
	switch (node.getKind()) {
	case FIELD:
		createGetterForFields(level, fields, annotationNode, true, lazy, onMethod);
		break;
	case TYPE:
		if (!onMethod.isEmpty()) {
			annotationNode.addError("'onMethod' is not supported for @Getter on a type.");
		}
		if (lazy) annotationNode.addError("'lazy' is not supported for @Getter on a type.");
		generateGetterForType(node, annotationNode, level, false);
		break;
	}
}
 
Example 9
Source File: HandleValue.java    From EasyMPermission with MIT License 5 votes vote down vote up
@Override public void handle(AnnotationValues<Value> annotation, JCAnnotation ast, JavacNode annotationNode) {
	@SuppressWarnings("deprecation")
	Class<? extends Annotation> oldExperimentalValue = lombok.experimental.Value.class;
	
	handleFlagUsage(annotationNode, ConfigurationKeys.VALUE_FLAG_USAGE, "@Value");
	
	deleteAnnotationIfNeccessary(annotationNode, Value.class, oldExperimentalValue);
	JavacNode typeNode = annotationNode.up();
	boolean notAClass = !isClass(typeNode);
	
	if (notAClass) {
		annotationNode.addError("@Value is only supported on a class.");
		return;
	}
	
	String staticConstructorName = annotation.getInstance().staticConstructor();
	
	if (!hasAnnotationAndDeleteIfNeccessary(NonFinal.class, typeNode)) {
		JCModifiers jcm = ((JCClassDecl) typeNode.get()).mods;
		if ((jcm.flags & Flags.FINAL) == 0) {
			jcm.flags |= Flags.FINAL;
			typeNode.rebuild();
		}
	}
	new HandleFieldDefaults().generateFieldDefaultsForType(typeNode, annotationNode, AccessLevel.PRIVATE, true, true);
	
	// TODO move this to the end OR move it to the top in eclipse.
	new HandleConstructor().generateAllArgsConstructor(typeNode, AccessLevel.PUBLIC, staticConstructorName, SkipIfConstructorExists.YES, annotationNode);
	new HandleGetter().generateGetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true);
	new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode);
	new HandleToString().generateToStringForType(typeNode, annotationNode);
}
 
Example 10
Source File: HandleUtilityClass.java    From EasyMPermission with MIT License 5 votes vote down vote up
@Override public void handle(AnnotationValues<UtilityClass> annotation, JCAnnotation ast, JavacNode annotationNode) {
	handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.UTLITY_CLASS_FLAG_USAGE, "@UtilityClass");
	
	deleteAnnotationIfNeccessary(annotationNode, UtilityClass.class);
	
	JavacNode typeNode = annotationNode.up();
	if (!checkLegality(typeNode, annotationNode)) return;
	changeModifiersAndGenerateConstructor(annotationNode.up(), annotationNode);
}
 
Example 11
Source File: HandleUtilityClass.java    From EasyMPermission with MIT License 5 votes vote down vote up
private static boolean checkLegality(JavacNode typeNode, JavacNode errorNode) {
	JCClassDecl typeDecl = null;
	if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get();
	long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags;
	boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION | Flags.ENUM)) != 0;
	
	if (typeDecl == null || notAClass) {
		errorNode.addError("@UtilityClass is only supported on a class (can't be an interface, enum, or annotation).");
		return false;
	}
	
	// It might be an inner class. This is okay, but only if it is / can be a static inner class. Thus, all of its parents have to be static inner classes until the top-level.
	JavacNode typeWalk = typeNode;
	while (true) {
		typeWalk = typeWalk.up();
		switch (typeWalk.getKind()) {
		case TYPE:
			JCClassDecl typeDef = (JCClassDecl) typeWalk.get();
			if ((typeDef.mods.flags & (Flags.STATIC | Flags.ANNOTATION | Flags.ENUM | Flags.INTERFACE)) != 0) continue;
			if (typeWalk.up().getKind() == Kind.COMPILATION_UNIT) return true;
			errorNode.addError("@UtilityClass automatically makes the class static, however, this class cannot be made static.");
			return false;
		case COMPILATION_UNIT:
			return true;
		default:
			errorNode.addError("@UtilityClass cannot be placed on a method local or anonymous inner class, or any class nested in such a class.");
			return false;
		}
	}
}
 
Example 12
Source File: HandleFieldDefaults.java    From EasyMPermission with MIT License 5 votes vote down vote up
@Override public void handle(AnnotationValues<FieldDefaults> annotation, JCAnnotation ast, JavacNode annotationNode) {
	handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.FIELD_DEFAULTS_FLAG_USAGE, "@FieldDefaults");
	
	deleteAnnotationIfNeccessary(annotationNode, FieldDefaults.class);
	deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
	JavacNode node = annotationNode.up();
	FieldDefaults instance = annotation.getInstance();
	AccessLevel level = instance.level();
	boolean makeFinal = instance.makeFinal();
	
	if (level == AccessLevel.NONE && !makeFinal) {
		annotationNode.addError("This does nothing; provide either level or makeFinal or both.");
		return;
	}
	
	if (level == AccessLevel.PACKAGE) {
		annotationNode.addError("Setting 'level' to PACKAGE does nothing. To force fields as package private, use the @PackagePrivate annotation on the field.");
	}
	
	if (!makeFinal && annotation.isExplicit("makeFinal")) {
		annotationNode.addError("Setting 'makeFinal' to false does nothing. To force fields to be non-final, use the @NonFinal annotation on the field.");
	}
	
	if (node == null) return;
	
	generateFieldDefaultsForType(node, annotationNode, level, makeFinal, false);
}
 
Example 13
Source File: HandleToString.java    From EasyMPermission with MIT License 5 votes vote down vote up
@Override public void handle(AnnotationValues<ToString> annotation, JCAnnotation ast, JavacNode annotationNode) {
	handleFlagUsage(annotationNode, ConfigurationKeys.TO_STRING_FLAG_USAGE, "@ToString");
	
	deleteAnnotationIfNeccessary(annotationNode, ToString.class);
	
	ToString ann = annotation.getInstance();
	List<String> excludes = List.from(ann.exclude());
	List<String> includes = List.from(ann.of());
	JavacNode typeNode = annotationNode.up();
	
	checkForBogusFieldNames(typeNode, annotation);
	
	Boolean callSuper = ann.callSuper();
	
	if (!annotation.isExplicit("callSuper")) callSuper = null;
	if (!annotation.isExplicit("exclude")) excludes = null;
	if (!annotation.isExplicit("of")) includes = null;
	
	if (excludes != null && includes != null) {
		excludes = null;
		annotation.setWarning("exclude", "exclude and of are mutually exclusive; the 'exclude' parameter will be ignored.");
	}
	
	Boolean doNotUseGettersConfiguration = annotationNode.getAst().readConfiguration(ConfigurationKeys.TO_STRING_DO_NOT_USE_GETTERS);
	boolean doNotUseGetters = annotation.isExplicit("doNotUseGetters") || doNotUseGettersConfiguration == null ? ann.doNotUseGetters() : doNotUseGettersConfiguration;
	FieldAccess fieldAccess = doNotUseGetters ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER;
	
	Boolean fieldNamesConfiguration = annotationNode.getAst().readConfiguration(ConfigurationKeys.TO_STRING_INCLUDE_FIELD_NAMES);
	boolean includeFieldNames = annotation.isExplicit("includeFieldNames") || fieldNamesConfiguration == null ? ann.includeFieldNames() : fieldNamesConfiguration;
	
	generateToString(typeNode, annotationNode, excludes, includes, includeFieldNames, callSuper, true, fieldAccess);
}
 
Example 14
Source File: HandleToString.java    From EasyMPermission with MIT License 5 votes vote down vote up
public static String getTypeName(JavacNode typeNode) {
	String typeName = ((JCClassDecl) typeNode.get()).name.toString();
	JavacNode upType = typeNode.up();
	while (upType.getKind() == Kind.TYPE) {
		typeName = ((JCClassDecl) upType.get()).name.toString() + "." + typeName;
		upType = upType.up();
	}
	return typeName;
}
 
Example 15
Source File: HandleExtensionMethod.java    From EasyMPermission with MIT License 5 votes vote down vote up
@Override
public void handle(final AnnotationValues<ExtensionMethod> annotation, final JCAnnotation source, final JavacNode annotationNode) {
	handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.EXTENSION_METHOD_FLAG_USAGE, "@ExtensionMethod");
	
	deleteAnnotationIfNeccessary(annotationNode, ExtensionMethod.class);
	JavacNode typeNode = annotationNode.up();
	boolean isClassOrEnum = isClassOrEnum(typeNode);
	
	if (!isClassOrEnum) {
		annotationNode.addError("@ExtensionMethod can only be used on a class or an enum");
		return;
	}
	
	boolean suppressBaseMethods = annotation.getInstance().suppressBaseMethods();
	
	List<Object> extensionProviders = annotation.getActualExpressions("value");
	if (extensionProviders.isEmpty()) {
		annotationNode.addError(String.format("@%s has no effect since no extension types were specified.", ExtensionMethod.class.getName()));
		return;
	}
	final List<Extension> extensions = getExtensions(annotationNode, extensionProviders);
	if (extensions.isEmpty()) return;
	
	new ExtensionMethodReplaceVisitor(annotationNode, extensions, suppressBaseMethods).replace();
	
	annotationNode.rebuild();
}
 
Example 16
Source File: JavacHandlerUtil.java    From EasyMPermission with MIT License 5 votes vote down vote up
static JCExpression createFieldAccessor(JavacTreeMaker maker, JavacNode field, FieldAccess fieldAccess, JCExpression receiver) {
	boolean lookForGetter = lookForGetter(field, fieldAccess);
	
	GetterMethod getter = lookForGetter ? findGetter(field) : null;
	JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
	
	if (getter == null) {
		if (receiver == null) {
			if ((fieldDecl.mods.flags & Flags.STATIC) == 0) {
				receiver = maker.Ident(field.toName("this"));
			} else {
				JavacNode containerNode = field.up();
				if (containerNode != null && containerNode.get() instanceof JCClassDecl) {
					JCClassDecl container = (JCClassDecl) field.up().get();
					receiver = maker.Ident(container.name);
				}
			}
		}
		
		return receiver == null ? maker.Ident(fieldDecl.name) : maker.Select(receiver, fieldDecl.name);
	}
	
	if (receiver == null) receiver = maker.Ident(field.toName("this"));
	JCMethodInvocation call = maker.Apply(List.<JCExpression>nil(),
			maker.Select(receiver, getter.name), List.<JCExpression>nil());
	return call;
}
 
Example 17
Source File: HandleLog.java    From EasyMPermission with MIT License 5 votes vote down vote up
public static void processAnnotation(LoggingFramework framework, AnnotationValues<?> annotation, JavacNode annotationNode, String loggerTopic) {
	deleteAnnotationIfNeccessary(annotationNode, framework.getAnnotationClass());

	JavacNode typeNode = annotationNode.up();
	switch (typeNode.getKind()) {
	case TYPE:
		String logFieldName = annotationNode.getAst().readConfiguration(ConfigurationKeys.LOG_ANY_FIELD_NAME);
		if (logFieldName == null) logFieldName = "log";
		
		boolean useStatic = !Boolean.FALSE.equals(annotationNode.getAst().readConfiguration(ConfigurationKeys.LOG_ANY_FIELD_IS_STATIC));
		
		if ((((JCClassDecl)typeNode.get()).mods.flags & Flags.INTERFACE) != 0) {
			annotationNode.addError("@Log is legal only on classes and enums.");
			return;
		}
		if (fieldExists(logFieldName, typeNode) != MemberExistsResult.NOT_EXISTS) {
			annotationNode.addWarning("Field '" + logFieldName + "' already exists.");
			return;
		}

		JCFieldAccess loggingType = selfType(typeNode);
		createField(framework, typeNode, loggingType, annotationNode.get(), logFieldName, useStatic, loggerTopic);
		break;
	default:
		annotationNode.addError("@Log is legal only on types.");
		break;
	}
}
 
Example 18
Source File: HandleSneakyThrows.java    From EasyMPermission with MIT License 5 votes vote down vote up
public void handleMethod(JavacNode annotation, JCMethodDecl method, Collection<String> exceptions) {
	JavacNode methodNode = annotation.up();
	
	if ( (method.mods.flags & Flags.ABSTRACT) != 0) {
		annotation.addError("@SneakyThrows can only be used on concrete methods.");
		return;
	}
	
	if (method.body == null || method.body.stats.isEmpty()) {
		generateEmptyBlockWarning(methodNode, annotation, false);
		return;
	}
	
	final JCStatement constructorCall = method.body.stats.get(0);
	final boolean isConstructorCall = isConstructorCall(constructorCall);
	List<JCStatement> contents = isConstructorCall ? method.body.stats.tail : method.body.stats;
	
	if (contents == null || contents.isEmpty()) {
		generateEmptyBlockWarning(methodNode, annotation, true);
		return;
	}
	
	for (String exception : exceptions) {
		contents = List.of(buildTryCatchBlock(methodNode, contents, exception, annotation.get()));
	}
	
	method.body.stats = isConstructorCall ? List.of(constructorCall).appendList(contents) : contents;
	methodNode.rebuild();
}
 
Example 19
Source File: HandleSynchronized.java    From EasyMPermission with MIT License 4 votes vote down vote up
@Override public void handle(AnnotationValues<Synchronized> annotation, JCAnnotation ast, JavacNode annotationNode) {
	handleFlagUsage(annotationNode, ConfigurationKeys.SYNCHRONIZED_FLAG_USAGE, "@Synchronized");
	
	if (inNetbeansEditor(annotationNode)) return;
	
	deleteAnnotationIfNeccessary(annotationNode, Synchronized.class);
	JavacNode methodNode = annotationNode.up();
	
	if (methodNode == null || methodNode.getKind() != Kind.METHOD || !(methodNode.get() instanceof JCMethodDecl)) {
		annotationNode.addError("@Synchronized is legal only on methods.");
		
		return;
	}
	
	JCMethodDecl method = (JCMethodDecl)methodNode.get();
	
	if ((method.mods.flags & Flags.ABSTRACT) != 0) {
		annotationNode.addError("@Synchronized is legal only on concrete methods.");
		
		return;
	}
	boolean isStatic = (method.mods.flags & Flags.STATIC) != 0;
	String lockName = annotation.getInstance().value();
	boolean autoMake = false;
	if (lockName.length() == 0) {
		autoMake = true;
		lockName = isStatic ? STATIC_LOCK_NAME : INSTANCE_LOCK_NAME;
	}
	
	JavacTreeMaker maker = methodNode.getTreeMaker().at(ast.pos);
	Context context = methodNode.getContext();
	
	if (fieldExists(lockName, methodNode) == MemberExistsResult.NOT_EXISTS) {
		if (!autoMake) {
			annotationNode.addError("The field " + lockName + " does not exist.");
			return;
		}
		JCExpression objectType = genJavaLangTypeRef(methodNode, ast.pos, "Object");
		//We use 'new Object[0];' because unlike 'new Object();', empty arrays *ARE* serializable!
		JCNewArray newObjectArray = maker.NewArray(genJavaLangTypeRef(methodNode, ast.pos, "Object"),
				List.<JCExpression>of(maker.Literal(CTC_INT, 0)), null);
		JCVariableDecl fieldDecl = recursiveSetGeneratedBy(maker.VarDef(
				maker.Modifiers(Flags.PRIVATE | Flags.FINAL | (isStatic ? Flags.STATIC : 0)),
				methodNode.toName(lockName), objectType, newObjectArray), ast, context);
		injectFieldAndMarkGenerated(methodNode.up(), fieldDecl);
	}
	
	if (method.body == null) return;
	
	JCExpression lockNode;
	if (isStatic) {
		lockNode = chainDots(methodNode, ast.pos, methodNode.up().getName(), lockName);
	} else {
		lockNode = maker.Select(maker.Ident(methodNode.toName("this")), methodNode.toName(lockName));
	}
	
	recursiveSetGeneratedBy(lockNode, ast, context);
	method.body = setGeneratedBy(maker.Block(0, List.<JCStatement>of(setGeneratedBy(maker.Synchronized(lockNode, method.body), ast, context))), ast, context);
	
	methodNode.rebuild();
}
 
Example 20
Source File: JavacHandlerUtil.java    From EasyMPermission with MIT License 4 votes vote down vote up
public static JavacNode upToTypeNode(JavacNode node) {
	if (node == null) throw new NullPointerException("node");
	while ((node != null) && !(node.get() instanceof JCClassDecl)) node = node.up();
	
	return node;
}