Skip to content
Snippets Groups Projects
Commit eb487dcd authored by Jesper's avatar Jesper Committed by Jesper Öqvist
Browse files

Deprecate list rewrites in legacy rewrite mode

Reverted removal of list rewrites in legacy rewrite mode.

A deprecation warning is reported when using list rewrites in legacy rewrite
mode. List rewrites cause an error in circular NTA rewrite mode.

see #141 (bitbucket)
parent eb85367e
No related branches found
No related tags found
No related merge requests found
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
attributes are now generated only for node types that have a rewrite, and attributes are now generated only for node types that have a rewrite, and
the attribute relies on the rewrite condition to decide when the rewrite the attribute relies on the rewrite condition to decide when the rewrite
has reached a final result. has reached a final result.
* Removed list rewrites. List rewrites were an undocumented feature that * List rewrite have been deprecated in legacy rewrite mode and removed in
circular NTA rewrite mode. List rewrites were an undocumented feature that
caused problems for attribute correctness by allowing nodes to change caused problems for attribute correctness by allowing nodes to change
position in a list after the AST was constructed. position in a list after the AST was constructed.
* Removed staged rewrites. Rewrite stages were an undocumented, * Removed staged rewrites. Rewrite stages were an undocumented,
......
...@@ -58,6 +58,8 @@ ClassBodyDecl ::= <Name> <FileName> <StartLine:int> <EndLine:int> <AspectName:St ...@@ -58,6 +58,8 @@ ClassBodyDecl ::= <Name> <FileName> <StartLine:int> <EndLine:int> <AspectName:St
Rewrite ::= <FileName> <StartLine:int> <EndLine:int> <AspectName>; Rewrite ::= <FileName> <StartLine:int> <EndLine:int> <AspectName>;
RewriteList : Rewrite;
/** A component of an AST node type declaration. */ /** A component of an AST node type declaration. */
abstract Component; abstract Component;
......
...@@ -140,6 +140,16 @@ aspect AttributeProblems { ...@@ -140,6 +140,16 @@ aspect AttributeProblems {
.sourceLine(getStartLine()) .sourceLine(getStartLine())
.buildError(); .buildError();
/**
* Create a new error object with relevant file name and line number.
*/
syn Problem Rewrite.error(String message) =
Problem.builder()
.message(message)
.sourceFile(getFileName())
.sourceLine(getStartLine())
.buildError();
/** /**
* Create a new error object with relevant file name and line number. * Create a new error object with relevant file name and line number.
*/ */
...@@ -160,6 +170,14 @@ aspect AttributeProblems { ...@@ -160,6 +170,14 @@ aspect AttributeProblems {
return warning(String.format(messagefmt, args)); return warning(String.format(messagefmt, args));
} }
/** Create a new warning with the relevant file name and line number. */
syn Problem Rewrite.warning(String message) =
Problem.builder()
.message(message)
.sourceFile(getFileName())
.sourceLine(getStartLine())
.buildWarning();
/** @return Previous equation for same synthesized attribute. */ /** @return Previous equation for same synthesized attribute. */
syn SynEq SynEq.prevEq() = hostClass().lookupSynEq(signature()); syn SynEq SynEq.prevEq() = hostClass().lookupSynEq(signature());
...@@ -482,4 +500,16 @@ aspect AttributeProblems { ...@@ -482,4 +500,16 @@ aspect AttributeProblems {
when root != null && root() == null when root != null && root() == null
to TypeDecl.attributeProblems() to TypeDecl.attributeProblems()
for hostClass(); for hostClass();
RewriteList contributes
error("list rewrites are not supported when using cnta rewrites")
when config().rewriteCircularNTA()
to TypeDecl.attributeProblems()
for hostClass();
RewriteList contributes
warning("list rewrites are deprecated and will be removed in a future version of JastAdd")
when config().legacyRewrite()
to TypeDecl.attributeProblems()
for hostClass();
} }
...@@ -85,6 +85,45 @@ public aspect Attributes { ...@@ -85,6 +85,45 @@ public aspect Attributes {
aspectMap.put(name, comment); aspectMap.put(name, comment);
} }
// Add attributes to AST.
public void Grammar.addRewriteList(
String className,
org.jastadd.jrag.AST.SimpleNode condition,
org.jastadd.jrag.AST.SimpleNode result,
String type,
String fileName,
int startLine,
int endLine,
String parentName,
String childName,
String aspectName) {
if (!config().rewriteEnabled()) {
error("can not use rewrites while rewrites are disabled (enable with --rewrite=regular)",
fileName, startLine);
return;
}
TypeDecl c = lookup(className);
if (c != null && c instanceof ASTDecl) {
RewriteList r = new RewriteList();
r.setFileName(fileName);
r.setStartLine(startLine);
r.setEndLine(endLine);
r.setCondition(condition);
r.setResult(result);
r.setReturnType(type);
r.setParentName(parentName);
r.setChildName(childName);
r.setAspectName(aspectName);
((ASTDecl)c).addRewrite(r);
} else if (c != null) {
error("can not rewrite to non AST class '" + className + "'", fileName, startLine);
} else {
error("can not rewrite to unknown class '" + className + "'", fileName, startLine);
}
}
public void Grammar.addRewrite( public void Grammar.addRewrite(
String className, String className,
org.jastadd.jrag.AST.SimpleNode condition, org.jastadd.jrag.AST.SimpleNode condition,
...@@ -1170,4 +1209,24 @@ public aspect Attributes { ...@@ -1170,4 +1209,24 @@ public aspect Attributes {
public void Rewrite.setReturnType(String type) { public void Rewrite.setReturnType(String type) {
returnType = type; returnType = type;
} }
public String RewriteList.parentName;
public String RewriteList.getParentName() {
return parentName;
}
public void RewriteList.setParentName(String name) {
parentName = name;
}
public String RewriteList.childName;
public String RewriteList.getChildName() {
return childName;
}
public void RewriteList.setChildName(String name) {
childName = name;
}
} }
...@@ -349,6 +349,12 @@ aspect JaddCodeGen { ...@@ -349,6 +349,12 @@ aspect JaddCodeGen {
} }
} }
/**
* @return <code>true</code> if the list$touched field is needed for this
* ASTDecl.
*/
syn boolean ASTDecl.needsListTouched() = config().legacyRewrite();
/** /**
* Generate implicit aspect declarations for the List type. * Generate implicit aspect declarations for the List type.
* *
...@@ -473,7 +479,9 @@ aspect JaddCodeGen { ...@@ -473,7 +479,9 @@ aspect JaddCodeGen {
out.println(ind + " * @apilevel internal"); out.println(ind + " * @apilevel internal");
out.println(ind + " */"); out.println(ind + " */");
out.println(ind + "public boolean " + name() + ".mayHaveRewrite() {"); out.println(ind + "public boolean " + name() + ".mayHaveRewrite() {");
if (hasRewrites()) { if (config().legacyRewrite() && name().equals(config().listType())) {
out.println(ind2 + "return true;");
} else if (hasRewrites()) {
out.println(ind2 + "return true;"); out.println(ind2 + "return true;");
} else { } else {
out.println(ind2 + "return false;"); out.println(ind2 + "return false;");
...@@ -524,17 +532,6 @@ aspect JaddCodeGen { ...@@ -524,17 +532,6 @@ aspect JaddCodeGen {
genIncremental(out); genIncremental(out);
} }
syn boolean ASTDecl.rewriteWithNoPhaseCondition() {
for (int i = 0; i < getNumRewrite(); i++) {
if (getRewrite(i).getCondition() == null)
return true;
String condition = Unparser.unparse(getRewrite(i).getCondition());
if (condition.indexOf("inRewritePhase") == -1 && condition.indexOf("inExactRewritePhase") == -1)
return true;
}
return superClass() instanceof ASTDecl && ((ASTDecl)superClass()).rewriteWithNoPhaseCondition();
}
public abstract void Component.jaddGen(int index, boolean publicModifier, ASTDecl decl); public abstract void Component.jaddGen(int index, boolean publicModifier, ASTDecl decl);
public void ListComponent.jaddGen(int index, boolean publicModifier, ASTDecl decl) { public void ListComponent.jaddGen(int index, boolean publicModifier, ASTDecl decl) {
......
...@@ -37,6 +37,9 @@ aspect Rewrites { ...@@ -37,6 +37,9 @@ aspect Rewrites {
tt.expand("ASTDecl.rewriteTo:begin", out); tt.expand("ASTDecl.rewriteTo:begin", out);
if (config().legacyRewrite() && name().equals(config().listType())) {
tt.expand("ASTDecl.emitRewrites.touch_list", out);
}
for (int i = 0; i < getNumRewrite(); i++) { for (int i = 0; i < getNumRewrite(); i++) {
Rewrite r = getRewrite(i); Rewrite r = getRewrite(i);
if (r.genRewrite(out, i)) { if (r.genRewrite(out, i)) {
...@@ -87,6 +90,18 @@ aspect Rewrites { ...@@ -87,6 +90,18 @@ aspect Rewrites {
} }
} }
public boolean RewriteList.genRewrite(PrintStream out, int index) {
TemplateContext tt = templateContext();
tt.expand("Rewrite.declaredat", out);
if (getCondition() != null) {
tt.bind("Condition", " && " + Unparser.unparse(getCondition()));
} else {
tt.bind("Condition", "");
}
tt.expand("RewriteList.genRewrite", out);
return false;
}
public void Rewrite.genRewriteCondition(PrintStream out, int index) { public void Rewrite.genRewriteCondition(PrintStream out, int index) {
TemplateContext tt = templateContext(); TemplateContext tt = templateContext();
tt.bind("RewriteIndex", "" + index); tt.bind("RewriteIndex", "" + index);
...@@ -114,6 +129,23 @@ aspect Rewrites { ...@@ -114,6 +129,23 @@ aspect Rewrites {
} }
} }
public void RewriteList.genRewritesExtra(PrintStream out, int index) {
String ind = config().indent;
String ind2 = config().ind(2);
if (getResult() instanceof org.jastadd.jrag.AST.ASTBlock) {
templateContext().expand("Rewrite.javaDoc:internal", out);
out.println(ind + "private " + getReturnType() + " rewrite"
+ getParentName() + "_" + getChildName() + "() {");
out.print(Unparser.unparse(getResult()));
out.println(ind + "}");
} else {
templateContext().expand("Rewrite.javaDoc:internal", out);
out.println(ind + "private " + getReturnType() + " rewrite" + getParentName() + "_" + getChildName() + "() {");
out.println(ind2 + "return " + Unparser.unparse(getResult()) + ";");
out.println(ind + "}");
}
}
syn lazy boolean ASTDecl.hasRewrites() = syn lazy boolean ASTDecl.hasRewrites() =
getNumRewrite() > 0 || (superClass() != null && superClass().hasRewrites()); getNumRewrite() > 0 || (superClass() != null && superClass().hasRewrites());
...@@ -169,4 +201,6 @@ aspect Rewrites { ...@@ -169,4 +201,6 @@ aspect Rewrites {
"", "",
"", "",
new List<Annotation>()); new List<Annotation>());
inh TypeDecl Rewrite.hostClass();
} }
...@@ -1138,15 +1138,22 @@ void AspectRewrite() : ...@@ -1138,15 +1138,22 @@ void AspectRewrite() :
SimpleNode eq; SimpleNode eq;
Token first, last; Token first, last;
Token parent = null;
Token child = null;
String type; String type;
} }
{ {
"rewrite" {cond = null; first = token;} t = <IDENTIFIER> { className = t.image; } "rewrite" {cond = null; first = token;} t = <IDENTIFIER> { className = t.image; }
[<IDENTIFIER> parent = <IDENTIFIER> "." child = <IDENTIFIER> <LPAREN> <RPAREN>]
<LBRACE> <LBRACE>
( ["when" { first = token; } <LPAREN> cond = Expression() <RPAREN>] ( ["when" { first = token; } <LPAREN> cond = Expression() <RPAREN>]
"to" type = AspectType() ( (eq = Expression() ";" { last = token; }) | eq = Block() { last = token; } ) "to" type = AspectType() ( (eq = Expression() ";" { last = token; }) | eq = Block() { last = token; } )
{ {
if (parent != null && child != null) {
root.addRewriteList(className, cond, eq, type, fileName, first.beginLine, last.endLine, parent.image, child.image, enclosingAspect);
} else {
root.addRewrite(className, cond, eq, type, fileName, first.beginLine, last.endLine, enclosingAspect); root.addRewrite(className, cond, eq, type, fileName, first.beginLine, last.endLine, enclosingAspect);
}
cond = null; cond = null;
} }
)+ )+
......
...@@ -51,8 +51,13 @@ $if(RewriteCircularNTA) ...@@ -51,8 +51,13 @@ $if(RewriteCircularNTA)
return i; return i;
} }
} }
$else
$if(LegacyRewrite)
// Legacy rewrites with rewrite in list can change child position, so update may be needed.
if (node.childIndex >= 0 && node.childIndex < numChildren && node == children[node.childIndex]) {
$else $else
if (node.childIndex >= 0) { if (node.childIndex >= 0) {
$endif
return node.childIndex; return node.childIndex;
} }
for (int i = 0; children != null && i < children.length; i++) { for (int i = 0; children != null && i < children.length; i++) {
......
...@@ -30,6 +30,10 @@ ...@@ -30,6 +30,10 @@
List.implicitAspectDecls [[ List.implicitAspectDecls [[
$if(#needsListTouched)
private boolean $List.list$$touched = true;
$endif
public $List<T> $List.add(T node) { public $List<T> $List.add(T node) {
$SynchBegin $SynchBegin
$if(DebugMode) $if(DebugMode)
...@@ -66,12 +70,18 @@ $endif ...@@ -66,12 +70,18 @@ $endif
public void $List.insertChild($ASTNode node, int i) { public void $List.insertChild($ASTNode node, int i) {
$SynchBegin $SynchBegin
$if(#needsListTouched)
list$$touched = true;
$endif
super.insertChild(node, i); super.insertChild(node, i);
$SynchEnd $SynchEnd
} }
public void $List.addChild(T node) { public void $List.addChild(T node) {
$SynchBegin $SynchBegin
$if(#needsListTouched)
list$$touched = true;
$endif
super.addChild(node); super.addChild(node);
$SynchEnd $SynchEnd
} }
...@@ -79,12 +89,23 @@ $endif ...@@ -79,12 +89,23 @@ $endif
/** @apilevel low-level */ /** @apilevel low-level */
public void $List.removeChild(int i) { public void $List.removeChild(int i) {
$SynchBegin $SynchBegin
$if(#needsListTouched)
list$$touched = true;
$endif
super.removeChild(i); super.removeChild(i);
$SynchEnd $SynchEnd
} }
public int $List.getNumChild() { public int $List.getNumChild() {
$SynchBegin $SynchBegin
$if(#needsListTouched)
if (list$$touched) {
for (int i = 0; i < getNumChildNoTransform(); i++) {
getChild(i);
}
list$$touched = false;
}
$endif
return getNumChildNoTransform(); return getNumChildNoTransform();
$SynchEnd $SynchEnd
} }
......
...@@ -30,6 +30,22 @@ ASTDecl.rewriteTo:begin [[ ...@@ -30,6 +30,22 @@ ASTDecl.rewriteTo:begin [[
public $ASTNode rewriteTo() { public $ASTNode rewriteTo() {
]] ]]
ASTDecl.emitRewrites.touch_list = [[
if (list$$touched) {
for(int i = 0 ; i < getNumChildNoTransform(); i++) {
getChild(i);
}
list$$touched = false;
$if(RewriteCircularNTA)
if (state().changeInCycle()) {
return this;
}
$else
return this;
$endif
}
]]
ASTDecl.rewriteTo:end:ASTNode [[ ASTDecl.rewriteTo:end:ASTNode [[
$if(LegacyRewrite) $if(LegacyRewrite)
if (state().peek() == $StateClass.REWRITE_CHANGE) { if (state().peek() == $StateClass.REWRITE_CHANGE) {
...@@ -85,6 +101,20 @@ Rewrite.genRewrite:unconditional [[ ...@@ -85,6 +101,20 @@ Rewrite.genRewrite:unconditional [[
return rewriteRule$RewriteIndex(); return rewriteRule$RewriteIndex();
]] ]]
RewriteList.genRewrite [[
if (getParent().getParent() instanceof #getParentName &&
((#getParentName)getParent().getParent()).#(getChildName)ListNoTransform() == getParent()$Condition) {
$List list = ($List) getParent();
int i = list.getIndexOfChild(this);
$List newList = rewrite#(getParentName)_#getChildName();
// The first child is set by the normal rewrite loop.
for(int j = 1; j < newList.getNumChildNoTransform(); j++) {
list.insertChild(newList.getChildNoTransform(j), ++i);
}
return newList.getChildNoTransform(0);
}
]]
Rewrite.javaDoc:internal [[ Rewrite.javaDoc:internal [[
/** /**
* #declaredat * #declaredat
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment