matches="/* synthetic */ @ref",
matchNode=Reference.class,
substitutes="<expanded>")
public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
if (node instanceof Reference) {
Reference ref = (Reference) node;
if (isSynthetic(ref.getIdentifier())) {
// noexpand needed since node itself may not be synthetic
// even though we now know it contains a synthetic identifier.
return rw.noexpand((Reference) node);
}
}
return NONE;
}
},
new Rule() {
@Override
@RuleDescription(
name="syntheticCalls",
synopsis="Pass through calls where the function name is synthetic.",
reason="A synthetic method may not be marked callable.",
matches="/* synthetic */ @f(@as*)",
substitutes="<expanded>")
public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
Map<String, ParseTreeNode> bindings = this.match(node);
if (bindings != null) {
Expression f = (Expression) bindings.get("f");
if (f instanceof Reference && isSynthetic((Reference) f)) {
return expandAll(node, scope);
}
}
return NONE;
}
},
new Rule() {
@Override
@RuleDescription(
name="syntheticMethodCalls",
synopsis="Pass through calls where the method name is synthetic.",
reason="A synthetic method may not be marked callable.",
matches="/* synthetic */ @o.@m(@as*)",
substitutes="<expanded>")
public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
Map<String, ParseTreeNode> bindings = this.match(node);
if (bindings != null && isSynthetic((Reference) bindings.get("m"))) {
return expandAll(node, scope);
}
return NONE;
}
},
new Rule() {
@Override
@RuleDescription(
name="syntheticDeletes",
synopsis="Pass through deletes of synthetic members.",
reason="A synthetic member may not be marked deletable.",
matches="/* synthetic */ delete @o.@m",
substitutes="<expanded>")
public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
Map<String, ParseTreeNode> bindings = this.match(node);
if (bindings != null && isSynthetic((Reference) bindings.get("m"))) {
return expandAll(node, scope);
}
return NONE;
}
},
new Rule() {
@Override
@RuleDescription(
name="syntheticReads",
synopsis="Pass through reads of synthetic members.",
reason="A synthetic member may not be marked readable.",
matches="/* synthetic */ @o.@m",
substitutes="<expanded>")
public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
Map<String, ParseTreeNode> bindings = this.match(node);
if (bindings != null && isSynthetic((Reference) bindings.get("m"))) {
return expandAll(node, scope);
}
return NONE;
}
},
new Rule() {
@Override
@RuleDescription(
name="syntheticSetMember",
synopsis="Pass through sets of synthetic members.",
reason="A synthetic member may not be marked writable.",
matches="/* synthetic */ @o.@m = @v",
substitutes="<expanded>")
public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
Map<String, ParseTreeNode> bindings = this.match(node);
if (bindings != null && isSynthetic((Reference) bindings.get("m"))) {
return expandAll(node, scope);
}
return NONE;
}
},
new Rule() {
@Override
@RuleDescription(
name="syntheticSetVar",
synopsis="Pass through set of synthetic vars.",
reason="A local variable might not be mentionable otherwise.",
matches="/* synthetic */ @lhs = @rhs",
substitutes="<expanded>")
public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
Map<String, ParseTreeNode> bindings = this.match(node);
if (bindings != null && bindings.get("lhs") instanceof Reference) {
if (isSynthetic((Reference) bindings.get("lhs"))) {
return expandAll(node, scope);
}
}
return NONE;
}
},
new Rule() {
@Override
@RuleDescription(
name="syntheticDeclaration",
synopsis="Pass through synthetic variables which are unmentionable.",
reason="Synthetic code might need local variables for safe-keeping.",
matches="/* synthetic */ var @v = @initial?;",
substitutes="<expanded>")
public ParseTreeNode fire(ParseTreeNode node, Scope scope) {
Map<String, ParseTreeNode> bindings = this.match(node);
if (bindings != null && isSynthetic((Identifier) bindings.get("v"))) {
Declaration d = (Declaration) expandAll(node, scope);
Statement s;
if (d.getInitializer() == null) {
s = new Noop(d.getFilePosition());
} else {
s = new ExpressionStmt(
Operation.createInfix(
Operator.ASSIGN, new Reference(d.getIdentifier()),
d.getInitializer()));
getRewriter().markTreeForSideEffect(s);
d.removeChild(d.getInitializer());
}
scope.addStartOfScopeStatement(d);