eclipse 自动为getter和setter添加中文注释

package org.eclipse.jdt.internal.corext.codemanipulation;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.NamingConventions;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.compiler.IScanner;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.CastExpression;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.NumberLiteral;
import org.eclipse.jdt.core.dom.ParenthesizedExpression;
import org.eclipse.jdt.core.dom.PostfixExpression;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.internal.core.SourceField;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.dom.NecessaryParenthesesChecker;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.JdtFlags;
import org.eclipse.jdt.ui.CodeGeneration;

/**
 * @author c_zhuzhonghui-001 2021-11-26 16:56:05
 * <pre>
 * 1.搜索关键字"CodeGeneration.getSetterComment"和"CodeGeneration.getGetterComment",分别在这两个查找到的内容下方添加一段相同的代码: 参考modify start... 和 modify end...之间的demo,并增加获取内容的方法getJavadoc
 * 2.打开Window > Preferences > Java > Code Style > Code Templates 展开Comments > 设置Getters及Setters的Pattern增加自定义的#{comment}
 * 3.替换eclipse/plugins/org.eclipse.jdt.ui_*.jar 中的 GetterSetterUtil.class
 * </pre>
 */
public class GetterSetterUtil {
	private static final String[] EMPTY = new String[0];

	public static String getGetterName(IField field, String[] excludedNames) throws JavaModelException {
		boolean useIs = StubUtility.useIsForBooleanGetters(field.getJavaProject());
		return getGetterName(field, excludedNames, useIs);
	}

	private static String getGetterName(IField field, String[] excludedNames, boolean useIsForBoolGetters) throws JavaModelException {
		if (excludedNames == null)
			excludedNames = EMPTY;

		return getGetterName(field.getJavaProject(), field.getElementName(), field.getFlags(), false, excludedNames);
	}

	public static String getGetterName(IVariableBinding variableType, IJavaProject project, String[] excludedNames, boolean isBoolean) {
		boolean useIs = (StubUtility.useIsForBooleanGetters(project)) && (isBoolean);
		return getGetterName(project, variableType.getName(), variableType.getModifiers(), useIs, excludedNames);
	}

	public static String getGetterName(IJavaProject project, String fieldName, int flags, boolean isBoolean, String[] excludedNames) {
		return NamingConventions.suggestGetterName(project, fieldName, flags, isBoolean, excludedNames);
	}

	public static String getSetterName(IVariableBinding variableType, IJavaProject project, String[] excludedNames, boolean isBoolean) {
		return getSetterName(project, variableType.getName(), variableType.getModifiers(), isBoolean, excludedNames);
	}

	public static String getSetterName(IJavaProject project, String fieldName, int flags, boolean isBoolean, String[] excludedNames) {
		boolean useIs = StubUtility.useIsForBooleanGetters(project);
		return NamingConventions.suggestSetterName(project, fieldName, flags, false, excludedNames);
	}

	public static String getSetterName(IField field, String[] excludedNames) throws JavaModelException {
		if (excludedNames == null)
			excludedNames = EMPTY;

		return getSetterName(field.getJavaProject(), field.getElementName(), field.getFlags(), JavaModelUtil.isBoolean(field), excludedNames);
	}

	public static IMethod getGetter(IField field) throws JavaModelException {
		String getterName = getGetterName(field, EMPTY, true);
		IMethod primaryCandidate = JavaModelUtil.findMethod(getterName, new String[0], false, field.getDeclaringType());
		if ((!(JavaModelUtil.isBoolean(field))) || ((primaryCandidate != null) && (primaryCandidate.exists())))
			return primaryCandidate;

		String secondCandidateName = getGetterName(field, EMPTY, false);
		return JavaModelUtil.findMethod(secondCandidateName, new String[0], false, field.getDeclaringType());
	}

	public static IMethod getSetter(IField field) throws JavaModelException {
		String[] args = { field.getTypeSignature() };
		return JavaModelUtil.findMethod(getSetterName(field, EMPTY), args, false, field.getDeclaringType());
	}

	public static String getSetterStub(IField field, String setterName, boolean addComments, int flags) throws CoreException {
		String fieldName = field.getElementName();
		IType parentType = field.getDeclaringType();

		String returnSig = field.getTypeSignature();
		String typeName = Signature.toString(returnSig);

		IJavaProject project = field.getJavaProject();

		String accessorName = StubUtility.getBaseName(field);
		String argname = StubUtility.suggestArgumentName(project, accessorName, EMPTY);

		boolean isStatic = Flags.isStatic(flags);
		boolean isSync = Flags.isSynchronized(flags);
		boolean isFinal = Flags.isFinal(flags);

		String lineDelim = "\n";
		StringBuffer buf = new StringBuffer();
		if (addComments) {
			String comment = CodeGeneration.getSetterComment(field.getCompilationUnit(), parentType.getTypeQualifiedName('.'), setterName, field.getElementName(), typeName, argname, accessorName, lineDelim);
			if (comment != null) {
				// modify start..............................
				String filedComment = getJavadoc((SourceField) field);
				// filedComment = filedComment == null ? "" : filedComment.replaceAll("/", "").replaceAll("\\*", "").trim();
				filedComment = filedComment == null ? "" : filedComment.trim();
				filedComment = filedComment.startsWith("/**") ? filedComment.replaceFirst("/\\**([ \f\n\r\t]*\\*)*", "") : filedComment.startsWith("//") ? filedComment.replaceFirst("/*", "") : filedComment;
				filedComment = filedComment.endsWith("*/") ? filedComment.substring(0, filedComment.lastIndexOf("*/")) : filedComment;
				// filedComment = filedComment.replaceAll("\n\t+", "\n");
				comment = comment.replace("#{comment}", filedComment.trim());
				// modify end..............................
				
				buf.append(comment);
				buf.append(lineDelim);
			}
		}
		buf.append(JdtFlags.getVisibilityString(flags));
		buf.append(' ');
		if (isStatic)
			buf.append("static ");
		if (isSync)
			buf.append("synchronized ");
		if (isFinal)
			buf.append("final ");

		buf.append("void ");
		buf.append(setterName);
		buf.append('(');
		buf.append(typeName);
		buf.append(' ');
		buf.append(argname);
		buf.append(") {");
		buf.append(lineDelim);

		boolean useThis = StubUtility.useThisForFieldAccess(project);
		if ((argname.equals(fieldName)) || ((useThis) && (!(isStatic))))
			if (isStatic)
				fieldName = parentType.getElementName() + '.' + fieldName;
			else
				fieldName = "this." + fieldName;

		String body = CodeGeneration.getSetterMethodBodyContent(field.getCompilationUnit(), parentType.getTypeQualifiedName('.'), setterName, fieldName, argname, lineDelim);
		if (body != null)
			buf.append(body);

		buf.append("}");
		return buf.toString();
	}

	public static String getGetterStub(IField field, String getterName, boolean addComments, int flags) throws CoreException {
		String fieldName = field.getElementName();
		IType parentType = field.getDeclaringType();

		boolean isStatic = Flags.isStatic(flags);
		boolean isSync = Flags.isSynchronized(flags);
		boolean isFinal = Flags.isFinal(flags);

		String typeName = Signature.toString(field.getTypeSignature());
		String accessorName = StubUtility.getBaseName(field);

		String lineDelim = "\n";
		StringBuffer buf = new StringBuffer();
		if (addComments) {
			String comment = CodeGeneration.getGetterComment(field.getCompilationUnit(), parentType.getTypeQualifiedName('.'), getterName, field.getElementName(), typeName, accessorName, lineDelim);
			if (comment != null) {
				// modify start..............................
				String filedComment = getJavadoc((SourceField) field);
				// filedComment = filedComment == null ? "" : filedComment.replaceAll("/", "").replaceAll("\\*", "").trim();
				filedComment = filedComment == null ? "" : filedComment.trim();
				filedComment = filedComment.startsWith("/**") ? filedComment.replaceFirst("/\\**([ \f\n\r\t]*\\*)*", "") : filedComment.startsWith("//") ? filedComment.replaceFirst("/*", "") : filedComment;
				filedComment = filedComment.endsWith("*/") ? filedComment.substring(0, filedComment.lastIndexOf("*/")) : filedComment;
				// filedComment = filedComment.replaceAll("\n\t+", "\n");
				comment = comment.replace("#{comment}", filedComment.trim());
				// modify end..............................
				
				buf.append(comment);
				buf.append(lineDelim);
			}
		}

		buf.append(JdtFlags.getVisibilityString(flags));
		buf.append(' ');
		if (isStatic)
			buf.append("static ");
		if (isSync)
			buf.append("synchronized ");
		if (isFinal)
			buf.append("final ");

		buf.append(typeName);
		buf.append(' ');
		buf.append(getterName);
		buf.append("() {");
		buf.append(lineDelim);

		boolean useThis = StubUtility.useThisForFieldAccess(field.getJavaProject());
		if ((useThis) && (!(isStatic))) {
			fieldName = "this." + fieldName;
		}

		String body = CodeGeneration.getGetterMethodBodyContent(field.getCompilationUnit(), parentType.getTypeQualifiedName('.'), getterName, fieldName, lineDelim);
		if (body != null)
			buf.append(body);

		buf.append("}");
		return buf.toString();
	}

	/**
	 * getJavadoc
	 */
	public static String getJavadoc(SourceField field) throws JavaModelException {
		IScanner scanner;
		ISourceRange range = field.getSourceRange();
		if (range == null)
			return null;
		IBuffer buf = null;
		if (field.isBinary()) {
			buf = field.getClassFile().getBuffer();
		} else {
			ICompilationUnit compilationUnit = field.getCompilationUnit();
			if (!(compilationUnit.isConsistent()))
				return null;

			buf = compilationUnit.getBuffer();
		}
		int start = range.getOffset();
		int length = range.getLength();
		if ((length > 0) && (buf.getChar(start) == '/')) {
			scanner = ToolFactory.createScanner(true, false, false, false);
			try {
				scanner.setSource(buf.getText(start, length).toCharArray());
				// 1001://
				// 1003:/**
				// 101:private
				// 5:String unitCode1
				// 64:;
				int terminal = scanner.getNextToken();
				char[] currentTokenSource = {};
				while (terminal == 1001 || terminal == 1003) {
					currentTokenSource = scanner.getCurrentTokenSource();
					terminal = scanner.getNextToken();
				}
				return new String(currentTokenSource);
				// return "A"+terminal+"A" + new String(scanner.getSource()) + "B" +new String(scanner.getRawTokenSource()) + "C" +new String(scanner.getCurrentTokenSource()) + "D";

			} catch (InvalidInputException localInvalidInputException) {
			} catch (IndexOutOfBoundsException localIndexOutOfBoundsException) {
			}
		}
		return null;
	}

	public static Expression getAssignedValue(ASTNode node, ASTRewrite astRewrite, Expression getterExpression, ITypeBinding variableType, boolean is50OrHigher) {
		InfixExpression.Operator op = null;
		AST ast = astRewrite.getAST();
		if (isNotInBlock(node))
			return null;
		if (node.getNodeType() == 7) {
			Assignment assignment = (Assignment) node;
			Expression rightHandSide = assignment.getRightHandSide();
			Expression copiedRightOp = (Expression) astRewrite.createCopyTarget(rightHandSide);
			if (assignment.getOperator() == Assignment.Operator.ASSIGN) {
				ITypeBinding rightHandSideType = rightHandSide.resolveTypeBinding();
				copiedRightOp = createNarrowCastIfNessecary(copiedRightOp, rightHandSideType, ast, variableType, is50OrHigher);
				return copiedRightOp;
			}
			if (getterExpression == null)
				return createInfixInvocationFromPostPrefixExpression(op, getterExpression, ast, variableType, is50OrHigher);
			InfixExpression infix = ast.newInfixExpression();
			infix.setLeftOperand(getterExpression);
			infix.setOperator(ASTNodes.convertToInfixOperator(assignment.getOperator()));
			ITypeBinding infixType = infix.resolveTypeBinding();
			if (NecessaryParenthesesChecker.needsParenthesesForRightOperand(rightHandSide, infix, variableType)) {
				ParenthesizedExpression p = ast.newParenthesizedExpression();
				p.setExpression(copiedRightOp);
				copiedRightOp = p;
			}
			infix.setRightOperand(copiedRightOp);
			return createNarrowCastIfNessecary(infix, infixType, ast, variableType, is50OrHigher);
		}
		if (node.getNodeType() == 37) {
			PostfixExpression po = (PostfixExpression) node;
			if (po.getOperator() == PostfixExpression.Operator.INCREMENT)
				op = InfixExpression.Operator.PLUS;
			if (po.getOperator() == PostfixExpression.Operator.DECREMENT)
				op = InfixExpression.Operator.MINUS;
		} else if (node.getNodeType() == 38) {
			PrefixExpression pe = (PrefixExpression) node;
			if (pe.getOperator() == PrefixExpression.Operator.INCREMENT)
				op = InfixExpression.Operator.PLUS;
			if (pe.getOperator() == PrefixExpression.Operator.DECREMENT)
				op = InfixExpression.Operator.MINUS;
		}
		if ((op != null) && (getterExpression != null))
			return createInfixInvocationFromPostPrefixExpression(op, getterExpression, ast, variableType, is50OrHigher);

		return null;
	}

	private static boolean isNotInBlock(ASTNode parent) {
		ASTNode statement = parent.getParent();
		boolean isStatement = statement.getNodeType() != 21;
		ASTNode block = statement.getParent();
		boolean isBlock = (block.getNodeType() == 8) || (block.getNodeType() == 50);
		boolean isControlStatemenBody = ASTNodes.isControlStatementBody(statement.getLocationInParent());
		return ((isStatement) || ((!(isBlock)) && (!(isControlStatemenBody))));
	}

	private static Expression createInfixInvocationFromPostPrefixExpression(InfixExpression.Operator operator, Expression getterExpression, AST ast, ITypeBinding variableType, boolean is50OrHigher) {
		InfixExpression infix = ast.newInfixExpression();
		infix.setLeftOperand(getterExpression);
		infix.setOperator(operator);
		NumberLiteral number = ast.newNumberLiteral();
		number.setToken("1");
		infix.setRightOperand(number);
		ITypeBinding infixType = infix.resolveTypeBinding();
		return createNarrowCastIfNessecary(infix, infixType, ast, variableType, is50OrHigher);
	}

	private static Expression createNarrowCastIfNessecary(Expression expression, ITypeBinding expressionType, AST ast, ITypeBinding variableType, boolean is50OrHigher) {
		PrimitiveType castTo = null;
		if (variableType.isEqualTo(expressionType))
			return expression;
		if (is50OrHigher) {
			if (ast.resolveWellKnownType("java.lang.Character").isEqualTo(variableType))
				castTo = ast.newPrimitiveType(PrimitiveType.CHAR);
			if (ast.resolveWellKnownType("java.lang.Byte").isEqualTo(variableType))
				castTo = ast.newPrimitiveType(PrimitiveType.BYTE);
			if (ast.resolveWellKnownType("java.lang.Short").isEqualTo(variableType))
				castTo = ast.newPrimitiveType(PrimitiveType.SHORT);
		}
		if (ast.resolveWellKnownType("char").isEqualTo(variableType))
			castTo = ast.newPrimitiveType(PrimitiveType.CHAR);
		if (ast.resolveWellKnownType("byte").isEqualTo(variableType))
			castTo = ast.newPrimitiveType(PrimitiveType.BYTE);
		if (ast.resolveWellKnownType("short").isEqualTo(variableType))
			castTo = ast.newPrimitiveType(PrimitiveType.SHORT);
		if (castTo != null) {
			CastExpression cast = ast.newCastExpression();
			if (NecessaryParenthesesChecker.needsParentheses(expression, cast, CastExpression.EXPRESSION_PROPERTY)) {
				ParenthesizedExpression parenthesized = ast.newParenthesizedExpression();
				parenthesized.setExpression(expression);
				cast.setExpression(parenthesized);
			} else {
				cast.setExpression(expression);
			}
			cast.setType(castTo);
			return cast;
		}
		return expression;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值