use of com.sun.tools.javac.tree.JCTree.JCAssign in project ceylon-compiler by ceylon.
the class StatementTransformer method transform.
public JCStatement transform(Tree.TryCatchStatement t) {
Tree.TryClause tryClause = t.getTryClause();
at(tryClause);
JCBlock tryBlock = transform(tryClause.getBlock());
Tree.ResourceList resList = tryClause.getResourceList();
if (resList != null) {
ArrayList<Tree.Resource> resources = new ArrayList<Tree.Resource>(resList.getResources());
Collections.reverse(resources);
for (Tree.Resource res : resources) {
List<JCStatement> stats = List.nil();
Tree.Expression resExpr;
String resVarName;
if (res.getExpression() != null) {
resExpr = res.getExpression();
resVarName = naming.newTemp("try");
} else if (res.getVariable() != null) {
Tree.Variable var = res.getVariable();
resExpr = var.getSpecifierExpression().getExpression();
resVarName = var.getIdentifier().getText();
} else {
throw new BugException(res, "missing resource expression");
}
boolean isDestroyable = typeFact().getDestroyableType().isSupertypeOf(resExpr.getTypeModel());
Type resVarType = resExpr.getTypeModel();
Type resVarExpectedType = isDestroyable ? typeFact().getDestroyableType() : typeFact().getObtainableType();
// CloseableType $var = resource-expression
JCExpression expr = expressionGen().transformExpression(resExpr);
JCExpression javaType = makeJavaType(resVarType);
JCVariableDecl var = makeVar(FINAL, resVarName, javaType, expr);
stats = stats.append(var);
if (!isDestroyable) {
JCExpression resVar0 = expressionGen().applyErasureAndBoxing(makeUnquotedIdent(resVarName), resVarType, true, BoxingStrategy.BOXED, resVarExpectedType);
JCMethodInvocation openCall = make().Apply(null, makeQualIdent(resVar0, "obtain"), List.<JCExpression>nil());
stats = stats.append(make().Exec(openCall));
}
// Exception $tpmex = null;
String innerExTmpVarName = naming.newTemp("ex");
JCExpression innerExType = makeJavaType(typeFact().getThrowableType(), JT_CATCH);
JCVariableDecl innerExTmpVar = makeVar(innerExTmpVarName, innerExType, makeNull());
stats = stats.append(innerExTmpVar);
// $tmpex = ex;
List<JCStatement> innerCatchStats = List.nil();
Name innerCatchVarName = naming.tempName("ex");
JCAssign exTmpAssign = make().Assign(makeUnquotedIdent(innerExTmpVarName), make().Ident(innerCatchVarName));
innerCatchStats = innerCatchStats.append(make().Exec(exTmpAssign));
// throw ex;
JCThrow innerCatchThrow = make().Throw(make().Ident(innerCatchVarName));
innerCatchStats = innerCatchStats.append(innerCatchThrow);
JCBlock innerCatchBlock = make().Block(0, innerCatchStats);
// $var.close() /// ((Closeable)$var).close()
JCExpression exarg = makeUnquotedIdent(innerExTmpVarName);
JCExpression resVar1 = expressionGen().applyErasureAndBoxing(makeUnquotedIdent(resVarName), resVarType, true, BoxingStrategy.BOXED, resVarExpectedType);
JCMethodInvocation closeCall = make().Apply(null, makeQualIdent(resVar1, isDestroyable ? "destroy" : "release"), List.<JCExpression>of(exarg));
JCBlock closeTryBlock = make().Block(0, List.<JCStatement>of(make().Exec(closeCall)));
// try { $var.close() } catch (Exception closex) { $tmpex.addSuppressed(closex); }
Name closeCatchVarName = naming.tempName("closex");
JCExpression closeCatchExType = makeJavaType(typeFact().getThrowableType(), JT_CATCH);
JCVariableDecl closeCatchVar = make().VarDef(make().Modifiers(Flags.FINAL), closeCatchVarName, closeCatchExType, null);
JCExpression addarg = make().Ident(closeCatchVarName);
JCMethodInvocation addSuppressedCall = make().Apply(null, makeQualIdent(makeUnquotedIdent(innerExTmpVarName), "addSuppressed"), List.<JCExpression>of(addarg));
JCCatch closeCatch = make().Catch(closeCatchVar, make().Block(0, List.<JCStatement>of(make().Exec(addSuppressedCall))));
JCTry closeTry = at(res).Try(closeTryBlock, List.<JCCatch>of(closeCatch), null);
// $var.close() /// ((Closeable)$var).close()
JCExpression exarg2 = makeUnquotedIdent(innerExTmpVarName);
JCExpression resVar2 = expressionGen().applyErasureAndBoxing(makeUnquotedIdent(resVarName), resVarType, true, BoxingStrategy.BOXED, resVarExpectedType);
JCMethodInvocation closeCall2 = make().Apply(null, makeQualIdent(resVar2, isDestroyable ? "destroy" : "release"), List.<JCExpression>of(exarg2));
// if ($tmpex != null) { ... } else { ... }
JCBinary closeCatchCond = make().Binary(JCTree.NE, makeUnquotedIdent(innerExTmpVarName), makeNull());
JCIf closeCatchIf = make().If(closeCatchCond, closeTry, make().Exec(closeCall2));
// try { .... } catch (Exception ex) { $tmpex=ex; throw ex; }
// finally { try { $var.close() } catch (Exception closex) { } }
JCExpression innerCatchExType = makeJavaType(typeFact().getThrowableType(), JT_CATCH);
JCVariableDecl innerCatchVar = make().VarDef(make().Modifiers(Flags.FINAL), innerCatchVarName, innerCatchExType, null);
JCCatch innerCatch = make().Catch(innerCatchVar, innerCatchBlock);
JCBlock innerFinallyBlock = make().Block(0, List.<JCStatement>of(closeCatchIf));
JCTry innerTry = at(res).Try(tryBlock, List.<JCCatch>of(innerCatch), innerFinallyBlock);
stats = stats.append(innerTry);
tryBlock = at(res).Block(0, stats);
}
}
final List<JCCatch> catches;
if (usePolymorphicCatches(t.getCatchClauses())) {
catches = transformCatchesPolymorphic(t.getCatchClauses());
} else {
catches = transformCatchesIfElseIf(t.getCatchClauses());
}
final JCBlock finallyBlock;
Tree.FinallyClause finallyClause = t.getFinallyClause();
if (finallyClause != null) {
at(finallyClause);
finallyBlock = transform(finallyClause.getBlock());
} else {
finallyBlock = null;
}
if (!catches.isEmpty() || finallyBlock != null) {
return at(t).Try(tryBlock, catches, finallyBlock);
} else {
return tryBlock;
}
}
use of com.sun.tools.javac.tree.JCTree.JCAssign in project robolectric by robolectric.
the class RobolectricShadow method matchClass.
@Override
public Description matchClass(ClassTree classTree, VisitorState state) {
List<Optional<SuggestedFix>> fixes = new ArrayList<>();
if (implementsClassMatcher.matches(classTree, state)) {
boolean inSdk = true;
JavacTrees trees = JavacTrees.instance(state.context);
for (AnnotationTree annotationTree : classTree.getModifiers().getAnnotations()) {
JCIdent ident = (JCIdent) annotationTree.getAnnotationType();
String annotationClassName = ident.sym.getQualifiedName().toString();
if ("org.robolectric.annotation.Implements".equals(annotationClassName)) {
for (ExpressionTree expressionTree : annotationTree.getArguments()) {
JCAssign jcAnnotation = (JCAssign) expressionTree;
if ("isInAndroidSdk".equals(state.getSourceForNode(jcAnnotation.lhs)) && "false".equals(state.getSourceForNode(jcAnnotation.rhs))) {
// shadows of classes not in the public Android SDK can keep their public methods.
inSdk = false;
}
}
}
}
if (inSdk) {
new ImplementationMethodScanner(state, fixes, trees).scan(state.getPath(), null);
}
}
SuggestedFix.Builder builder = SuggestedFix.builder();
for (Optional<SuggestedFix> fix : fixes) {
fix.ifPresent(builder::merge);
}
if (builder.isEmpty()) {
return Description.NO_MATCH;
} else {
return describeMatch(classTree, builder.build());
}
}
use of com.sun.tools.javac.tree.JCTree.JCAssign in project lombok by rzwitserloot.
the class JavacHandlerUtil method unboxAndRemoveAnnotationParameter.
static List<JCAnnotation> unboxAndRemoveAnnotationParameter(JCAnnotation ast, String parameterName, String errorName, JavacNode annotationNode) {
ListBuffer<JCExpression> params = new ListBuffer<JCExpression>();
ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
outer: for (JCExpression param : ast.args) {
boolean allowRaw;
String nameOfParam = "value";
JCExpression valueOfParam = null;
if (param instanceof JCAssign) {
JCAssign assign = (JCAssign) param;
if (assign.lhs instanceof JCIdent) {
JCIdent ident = (JCIdent) assign.lhs;
nameOfParam = ident.name.toString();
}
valueOfParam = assign.rhs;
}
/* strip trailing underscores */
{
int lastIdx;
for (lastIdx = nameOfParam.length(); lastIdx > 0; lastIdx--) {
if (nameOfParam.charAt(lastIdx - 1) != '_')
break;
}
allowRaw = lastIdx < nameOfParam.length();
nameOfParam = nameOfParam.substring(0, lastIdx);
}
if (!parameterName.equals(nameOfParam)) {
params.append(param);
continue outer;
}
int endPos = Javac.getEndPosition(param.pos(), (JCCompilationUnit) annotationNode.top().get());
annotationNode.getAst().removeFromDeferredDiagnostics(param.pos, endPos);
if (valueOfParam instanceof JCAnnotation) {
String dummyAnnotationName = ((JCAnnotation) valueOfParam).annotationType.toString();
dummyAnnotationName = dummyAnnotationName.replace("_", "").replace("$", "").replace("x", "").replace("X", "");
if (dummyAnnotationName.length() > 0) {
if (allowRaw) {
result.append((JCAnnotation) valueOfParam);
} else {
addError(errorName, annotationNode);
continue outer;
}
} else {
for (JCExpression expr : ((JCAnnotation) valueOfParam).args) {
if (expr instanceof JCAssign && ((JCAssign) expr).lhs instanceof JCIdent) {
JCIdent id = (JCIdent) ((JCAssign) expr).lhs;
if ("value".equals(id.name.toString())) {
expr = ((JCAssign) expr).rhs;
} else {
addError(errorName, annotationNode);
}
}
if (expr instanceof JCAnnotation) {
result.append((JCAnnotation) expr);
} else if (expr instanceof JCNewArray) {
for (JCExpression expr2 : ((JCNewArray) expr).elems) {
if (expr2 instanceof JCAnnotation) {
result.append((JCAnnotation) expr2);
} else {
addError(errorName, annotationNode);
continue outer;
}
}
} else {
addError(errorName, annotationNode);
continue outer;
}
}
}
} else if (valueOfParam instanceof JCNewArray) {
JCNewArray arr = (JCNewArray) valueOfParam;
if (arr.elems.isEmpty()) {
// Just remove it, this is always fine.
} else if (allowRaw) {
for (JCExpression jce : arr.elems) {
if (jce instanceof JCAnnotation)
result.append((JCAnnotation) jce);
else
addError(errorName, annotationNode);
}
} else {
addError(errorName, annotationNode);
}
} else {
addError(errorName, annotationNode);
}
}
ast.args = params.toList();
return result.toList();
}
use of com.sun.tools.javac.tree.JCTree.JCAssign in project lombok by rzwitserloot.
the class JavacHandlerUtil method addAnnotation.
private static void addAnnotation(JCModifiers mods, JavacNode node, int pos, JCTree source, Context context, String annotationTypeFqn, JCExpression arg) {
boolean isJavaLangBased;
String simpleName;
{
int idx = annotationTypeFqn.lastIndexOf('.');
simpleName = idx == -1 ? annotationTypeFqn : annotationTypeFqn.substring(idx + 1);
isJavaLangBased = idx == 9 && annotationTypeFqn.regionMatches(0, "java.lang.", 0, 10);
}
for (JCAnnotation ann : mods.annotations) {
JCTree annType = ann.getAnnotationType();
if (annType instanceof JCIdent) {
Name lastPart = ((JCIdent) annType).name;
if (lastPart.contentEquals(simpleName))
return;
}
if (annType instanceof JCFieldAccess) {
if (annType.toString().equals(annotationTypeFqn))
return;
}
}
JavacTreeMaker maker = node.getTreeMaker();
JCExpression annType = isJavaLangBased ? genJavaLangTypeRef(node, simpleName) : chainDotsString(node, annotationTypeFqn);
annType.pos = pos;
if (arg != null) {
arg.pos = pos;
if (arg instanceof JCAssign) {
((JCAssign) arg).lhs.pos = pos;
((JCAssign) arg).rhs.pos = pos;
}
}
List<JCExpression> argList = arg != null ? List.of(arg) : List.<JCExpression>nil();
JCAnnotation annotation = recursiveSetGeneratedBy(maker.Annotation(annType, argList), source, context);
annotation.pos = pos;
mods.annotations = mods.annotations.append(annotation);
}
use of com.sun.tools.javac.tree.JCTree.JCAssign in project lombok by rzwitserloot.
the class JavacHandlerUtil method createAnnotation.
/**
* Creates an instance of {@code AnnotationValues} for the provided AST Node.
*
* @param type An annotation class type, such as {@code lombok.Getter.class}.
* @param node A Lombok AST node representing an annotation in source code.
*/
public static <A extends Annotation> AnnotationValues<A> createAnnotation(Class<A> type, final JavacNode node) {
Map<String, AnnotationValue> values = new HashMap<String, AnnotationValue>();
JCAnnotation anno = (JCAnnotation) node.get();
List<JCExpression> arguments = anno.getArguments();
for (JCExpression arg : arguments) {
String mName;
JCExpression rhs;
java.util.List<String> raws = new ArrayList<String>();
java.util.List<Object> guesses = new ArrayList<Object>();
java.util.List<Object> expressions = new ArrayList<Object>();
final java.util.List<DiagnosticPosition> positions = new ArrayList<DiagnosticPosition>();
if (arg instanceof JCAssign) {
JCAssign assign = (JCAssign) arg;
mName = assign.lhs.toString();
rhs = assign.rhs;
} else {
rhs = arg;
mName = "value";
}
if (rhs instanceof JCNewArray) {
List<JCExpression> elems = ((JCNewArray) rhs).elems;
for (JCExpression inner : elems) {
raws.add(inner.toString());
expressions.add(inner);
guesses.add(calculateGuess(inner));
positions.add(inner.pos());
}
} else {
raws.add(rhs.toString());
expressions.add(rhs);
guesses.add(calculateGuess(rhs));
positions.add(rhs.pos());
}
values.put(mName, new AnnotationValue(node, raws, expressions, guesses, true) {
@Override
public void setError(String message, int valueIdx) {
if (valueIdx < 0)
node.addError(message);
else
node.addError(message, positions.get(valueIdx));
}
@Override
public void setWarning(String message, int valueIdx) {
if (valueIdx < 0)
node.addWarning(message);
else
node.addWarning(message, positions.get(valueIdx));
}
});
}
for (Method m : type.getDeclaredMethods()) {
if (!Modifier.isPublic(m.getModifiers()))
continue;
String name = m.getName();
if (!values.containsKey(name)) {
values.put(name, new AnnotationValue(node, new ArrayList<String>(), new ArrayList<Object>(), new ArrayList<Object>(), false) {
@Override
public void setError(String message, int valueIdx) {
node.addError(message);
}
@Override
public void setWarning(String message, int valueIdx) {
node.addWarning(message);
}
});
}
}
return new AnnotationValues<A>(type, values, node);
}
Aggregations