Skip to content
Snippets Groups Projects
Commit 9430332b authored by Jesper's avatar Jesper
Browse files

Cache declarations in aspects

Added support for cache declarations in aspects. This makes separate cache
configuration files obsolete, so the support for cache configuration files has
been removed. The --cache=implicit and --cache=config options were also
removed. The --cache=analyze option now generates a cache analyzer that can
generate a cache configuration aspect.

fixes #252 (bitbucket)
parent 16d2d3ed
No related branches found
No related tags found
No related merge requests found
Showing with 346 additions and 305 deletions
......@@ -22,7 +22,7 @@ Abstract;
Annotation ::= <Annotation:String>;
abstract AttrDecl ::= Parameter* <Name> <Type> <Lazy:boolean> <FileName> <StartLine:int>
abstract AttrDecl ::= Parameter* <Name> <Type> <CacheMode:CacheMode> <FileName> <StartLine:int>
<EndLine:int> <Final:boolean> <NTA:boolean> <Comment:String> <AspectName:String> Annotation*;
SynDecl : AttrDecl;
......
......@@ -27,7 +27,8 @@
*/
import org.jastadd.ast.AST.*;
import java.util.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
......@@ -157,46 +158,78 @@ public aspect Attributes {
}
}
public class CacheDecl {
public String mode;
public String hostName;
public String attrName;
public String signature;
public String fileName;
public int startLine;
}
public ArrayList<CacheDecl> Grammar.cacheDecls = new ArrayList<CacheDecl>();
/**
* Configures the caching behavior for an attribute.
*
* @param cacheConfig The cache configuration, should be "cache" or "uncache"
* @param mode The cache configuration, should be "cache" or "uncache"
* @param hostName The node type hosting the attribute
* @param attrName The attribute name
* @param paramList The list of attribute parameters
* @param fileName The name of the file with the attribute declaration
* @param startLine The line of the attribute declaration
*/
public void Grammar.setAttrDeclLazy(String cacheConfig, String hostName, String attrName,
public void Grammar.setAttributeCacheMode(String mode, String hostName, String attrName,
org.jastadd.ast.AST.List paramList, String fileName, int startLine) {
CacheDecl decl = new CacheDecl();
decl.mode = mode;
decl.hostName = hostName;
decl.attrName = attrName;
decl.fileName = fileName;
decl.startLine = startLine;
StringBuilder signature = new StringBuilder();
signature.append(attrName);
for (int i = 0; i < paramList.getNumChild(); i++) {
signature.append("_" + ((Parameter) paramList.getChild(i)).getTypeInSignature());
}
decl.signature = signature.toString();
cacheDecls.add(decl);
}
public void Grammar.applyCacheMode(CacheDecl decl, Collection<Problem> problems) {
// Lookup type.
TypeDecl type = lookup(hostName);
TypeDecl type = lookup(decl.hostName);
if (type == null) {
error("can not find attribute " + attrName + " in unknown class " + hostName, fileName, startLine);
problems.add(Problem.builder()
.message("can not find attribute %s in unknown class %s", decl.attrName, decl.hostName)
.sourceFile(decl.fileName)
.sourceLine(decl.startLine)
.buildError());
return;
}
// Build signature for lookup of inherited attribute.
StringBuilder signBuf = new StringBuilder();
signBuf.append(attrName);
for (int i = 0; i < paramList.getNumChild(); i++) {
signBuf.append("_" + ((Parameter)paramList.getChild(i)).getTypeInSignature());
}
// Lookup attribute; first 'syn' then 'inh'.
AttrDecl attr = null;
String signature = signBuf.toString();
if ((attr = type.lookupSynDecl(signature)) == null
&& (attr = type.lookupInhDecl(signature)) == null) {
error("can not find attribute " + attrName + " in class " + hostName);
if ((attr = type.lookupSynDecl(decl.signature)) == null
&& (attr = type.lookupInhDecl(decl.signature)) == null) {
problems.add(Problem.builder()
.message("can not find attribute %s.%s", decl.hostName, decl.attrName)
.sourceFile(decl.fileName)
.sourceLine(decl.startLine)
.buildError());
return;
}
// Configure attribute caching.
if (cacheConfig.equals("cache")) {
attr.setLazy(true);
} else if (cacheConfig.equals("uncache")) {
attr.setLazy(false);
if (decl.mode.equals("cache")) {
attr.setCacheMode(CacheMode.CACHED);
} else if (decl.mode.equals("uncache")) {
attr.setCacheMode(CacheMode.UNCACHED);
} else {
error("unknown configuration " + cacheConfig + " for attribute " + hostName + "."
+ attrName, fileName, startLine);
problems.add(Problem.builder()
.message("unknown configuration %s for attribute %s.%s", decl.mode, decl.hostName,
decl.attrName)
.sourceFile(decl.fileName)
.sourceLine(decl.startLine)
.buildError());
}
}
......@@ -235,7 +268,7 @@ public aspect Attributes {
parameterList,
name,
type,
isLazy | isNTA,
(isLazy | isNTA) ? CacheMode.LAZY : CacheMode.DEFAULT,
fileName,
startLine,
endLine,
......@@ -243,8 +276,7 @@ public aspect Attributes {
isNTA,
Unparser.unparseComment(node),
aspectName,
new List()
);
new List());
for (String annotation : annotations) {
decl.addAnnotation(new Annotation(annotation));
}
......@@ -289,7 +321,7 @@ public aspect Attributes {
parameterList,
name,
type,
isLazy | isNTA,
(isLazy | isNTA) ? CacheMode.LAZY : CacheMode.DEFAULT,
fileName,
startLine,
endLine,
......
......@@ -413,7 +413,7 @@ aspect CollectionAttributes {
CollDecl decl = new CollDecl();
decl.setName(name);
decl.setType(type);
decl.setLazy(true);
decl.setCacheMode(CacheMode.LAZY);
decl.setFileName(fileName);
decl.setStartLine(startLine);
decl.setEndLine(endLine);
......
......@@ -85,17 +85,31 @@ aspect JragCodeGen {
syn String Rewrite.sourceLocation() = ASTNode.sourceLocation(getFileName(), getStartLine());
syn boolean AttrDecl.isLazy() =
config().cacheAll() || declaredNTA() || (!config().cacheNone() && getLazy());
/**
* Decide if an attribute should be cached based on the cache mode and
* current global configuration.
*/
syn boolean ASTNode.shouldCache(CacheMode mode) {
switch (mode) {
case DEFAULT:
return config().cacheAll();
case LAZY:
return !config().cacheNone();
case CACHED:
return true;
case UNCACHED:
return false;
}
throw new Error("unhandled cache mode");
}
syn boolean AttrDecl.isLazy() = declaredNTA() || shouldCache(getCacheMode());
eq SynDecl.isLazy() =
config().cacheAll() || declaredNTA() || (!config().cacheNone() && getLazy());
eq SynDecl.isLazy() = declaredNTA() || shouldCache(getCacheMode());
eq InhDecl.isLazy() =
config().cacheAll() || declaredNTA() || (!config().cacheNone() && getLazy());
eq InhDecl.isLazy() = declaredNTA() || shouldCache(getCacheMode());
eq CollDecl.isLazy() =
config().cacheAll() || !config().cacheNone() && (declaredNTA() || getLazy());
eq CollDecl.isLazy() = declaredNTA() || shouldCache(getCacheMode());
public String Grammar.genImportsList() {
Set imports = new LinkedHashSet();
......
......@@ -57,7 +57,6 @@ aspect IncrementalDDG {
}
if (config().incrementalLevelParam() ||
config().incrementalLevelAttr()) {
if (name().equals(config().astNodeType())) {
tt.expand("ASTDecl.createASTHandlers", out);
}
......@@ -65,24 +64,26 @@ aspect IncrementalDDG {
ArrayList list = new ArrayList();
for (int k = 0; k < getNumSynDecl(); k++) {
AttrDecl attr = getSynDecl(k);
if (attr.isLazy() || attr.isCircular())
if (attr.isLazy() || attr.isCircular()) {
list.add(attr);
}
}
for (int k = 0; k < getNumInhDecl(); k++) {
AttrDecl attr = getInhDecl(k);
if (attr.isLazy() || attr.isCircular())
if (attr.isLazy() || attr.isCircular()) {
list.add(attr);
}
}
for (CollDecl decl: interfaceCollDecls()) {
list.add(decl);
}
for (CollDecl decl: getCollDeclList()) {
list.add(decl);
}
// attribute code
// Attribute code.
for (Iterator itr = list.iterator(); itr.hasNext();) {
AttrDecl attr = (AttrDecl)itr.next();
tt.bind("AttributeName", attr.signature());// TODO rename template variable?
tt.bind("AttributeName", attr.signature()); // TODO(joqvist): rename template variable?
tt.bind("IsParameterized", attr.getNumParameter() > 0);
tt.expand("ASTDecl.createAttributeHandler", out);
}
......@@ -94,16 +95,21 @@ aspect IncrementalDDG {
* This only applies for the incremental param configuration.
*/
public String ASTDecl.genIncrementalInitChildHandlers() {
if (!config().incremental()) return "";
if (!config().incremental()) {
return "";
} else {
TemplateContext tt = templateContext();
return tt.expand("ASTDecl.incrementalInitChildHandlers");
}
}
/**
* Generate code for copying of DDG nodes.
*/
public void ASTDecl.genIncrementalCopyHandlers(PrintWriter out) {
if (!config().incremental()) return;
if (!config().incremental()) {
return;
}
TemplateContext tt = templateContext();
tt.bind("IsRegionRoot", isRegionRoot());
tt.bind("CopyTokenHandlers", emitCopyTokenHandlersString());
......@@ -115,7 +121,7 @@ aspect IncrementalDDG {
* Emit string for copying of token DDG nodes in a node.
*/
public String ASTDecl.emitCopyTokenHandlersString() {
StringBuffer res = new StringBuffer();
StringBuilder res = new StringBuilder();
if (config().incrementalLevelParam() || config().incrementalLevelAttr()) {
TemplateContext tt = templateContext();
for (int c = 0; c < getNumComponent(); c++) {
......@@ -133,20 +139,22 @@ aspect IncrementalDDG {
* Emit string for copying of attribute DDG nodes in a node.
*/
public String ASTDecl.emitCopyAttributeHandlersString() {
StringBuffer res = new StringBuffer();
StringBuilder res = new StringBuilder();
if (config().incrementalLevelParam() || config().incrementalLevelAttr()) {
// Collect attributes.
ArrayList list = new ArrayList();
for (int k = 0; k < getNumSynDecl(); k++) {
AttrDecl attr = getSynDecl(k);
if (attr != null && (attr.isLazy() || attr.isCircular()))
if (attr != null && (attr.isLazy() || attr.isCircular())) {
list.add(attr);
}
}
for (int k = 0; k < getNumInhDecl(); k++) {
AttrDecl attr = getInhDecl(k);
if (attr != null && (attr.isLazy() || attr.isCircular()))
if (attr != null && (attr.isLazy() || attr.isCircular())) {
list.add(attr);
}
}
// Attribute code.
TemplateContext tt = templateContext();
for (Iterator itr = list.iterator(); itr.hasNext();) {
......@@ -166,7 +174,9 @@ aspect IncrementalDDG {
* and tracking of region dependencies.
*/
public void ASTDecl.genIncrementalRegions(PrintWriter out) {
if (!config().incremental()) return;
if (!config().incremental()) {
return;
}
TemplateContext tt = templateContext();
tt.bind("IsRegionRoot", isRegionRoot());
if (config().incrementalLevelNode()) {
......
......@@ -366,8 +366,6 @@ public class Configuration {
.acceptMultipleValues(false)
.addAcceptedValue("none", "disable attribute caching")
.addAcceptedValue("all", "cache all attributes")
.addAcceptedValue("config", "cache attributes according to a given .config file")
.addAcceptedValue("implicit", "cache all attribute but also read a .config file that takes precedence")
.addAcceptedValue("analyze", "analyze the cache use during evaluation (when all attributes are cached)\n"
+ "the result is available via the API in org.jastadd.CacheAnalyzer")
.additionalDescription(".config files have the following format:\n"
......@@ -516,7 +514,8 @@ public class Configuration {
// Configuration object must be set before creating root template context!
TemplateContext tt = root.templateContext();
// Global locking
// Configure global locking.
// TODO(joqvist): remove this.
tt.bind("SynchBegin", synchronizedBlockBegin(tt));
tt.bind("SynchEnd", synchronizedBlockEnd(tt));
......@@ -532,7 +531,7 @@ public class Configuration {
tt.bind("PackageDecl", "package " + packageName + ";");
}
// Default attribute cache sets/maps
// Default attribute cache sets/maps.
tt.bind("DefaultMapType", typeDefaultMap());
tt.bind("DefaultSetType", typeDefaultSet());
......@@ -616,29 +615,25 @@ public class Configuration {
for (String filename: filenames) {
if (!(filename.endsWith(".ast")
|| filename.endsWith(".jrag")
|| filename.endsWith(".jadd")
|| filename.endsWith(".config"))) {
out.println("Error: Unrecognized file extension: " + filename);
|| filename.endsWith(".jadd"))) {
out.format("Error: Unrecognized file extension: %s%n", filename);
return true;
}
}
File outputDir = outputDir();
if (!outputDir.exists()) {
out.println("Error: Output directory " + outputDir.getAbsolutePath() +
" does not exist");
out.format("Error: Output directory %s does not exist%n", outputDir.getAbsolutePath());
return true;
}
if (!outputDir.isDirectory()) {
out.println("Error: Output directory " + outputDir.getAbsolutePath() +
" is not a directory");
out.format("Error: Output directory %s is not a directory%n", outputDir.getAbsolutePath());
return true;
}
if (!outputDir.canWrite()) {
out.println("Error: Output directory " + outputDir.getAbsolutePath() +
" is write protected");
out.format("Error: Output directory %s is write protected%n", outputDir.getAbsolutePath());
return true;
}
......@@ -735,58 +730,40 @@ public class Configuration {
*/
public Collection<String> getFiles() {
Collection<String> files = new ArrayList<String>();
for (String filename: filenames) {
if (filename.endsWith(".ast") || filename.endsWith(".jrag") || filename.endsWith(".jadd")) {
files.add(filename);
}
}
return files;
}
/**
* @return cache file list
*/
public Collection<String> getCacheFiles() {
Collection<String> cacheFiles = new ArrayList<String>();
for (String filename: filenames) {
if (filename.endsWith(".config")) {
cacheFiles.add(filename);
}
}
return cacheFiles;
}
/**
* Print help
* @param out Output stream to print help to.
*/
public void printHelp(PrintStream out) {
out.println("This program reads a number of .jrag, .jadd, and .ast files");
out.println("and creates the nodes in the abstract syntax tree");
out.println();
out.println("The .jrag source files may contain declarations of synthesized ");
out.println("and inherited attributes and their corresponding equations.");
out.println("It may also contain ordinary Java methods and fields.");
out.println("and generates the Java classes for the abstract syntax tree.");
out.println();
out.println("Source file syntax can be found at http://jastadd.org");
out.println("Source files contain declarations of synthesized ");
out.println("and inherited attributes and their corresponding equations,");
out.println("as well as ordinary Java methods and fields.");
out.println("Source file syntax is documented at http://jastadd.org");
out.println();
out.println("Options:");
argParser().printHelp(out);
out.println();
out.println("Arguments:");
out.println("Names of .ast, .jrag, .jadd and .config source files");
out.println(" Names of abstract grammr (.ast) and aspect (.jrag and .jadd) files.");
out.println();
out.println("Example: The following command reads and translates files NameAnalysis.jrag");
out.println("and TypeAnalysis.jrag, weaves PrettyPrint.jadd into the abstract syntax tree");
out.println("defined in the grammar Toy.ast.");
out.println("Example: The following command reads and translates NameAnalysis.jrag,");
out.println("and weaves PrettyPrint.jadd into the abstract syntax classes");
out.println("defined in the grammar file Toy.ast.");
out.println("The result is the generated classes for the nodes in the AST that are placed");
out.println("in the package ast.");
out.println();
out.println("java -jar jastadd2.jar --package=ast Toy.ast NameAnalysis.jrag TypeAnalysis.jrag PrettyPrinter.jadd");
out.println("java -jar jastadd2.jar --package=ast Toy.ast NameAnalysis.jrag PrettyPrint.jadd");
}
/**
......@@ -823,8 +800,7 @@ public class Configuration {
* @return <code>true</code> if the --tracing option is enabled
*/
public boolean tracingEnabled() {
return !tracingOption.hasValue("none") ||
cacheAnalyzeEnabled();
return !tracingOption.hasValue("none") || cacheAnalyzeEnabled();
}
/**
......@@ -1000,9 +976,8 @@ public class Configuration {
* @return {@code true} if everything should be cached
*/
public boolean cacheAll() {
return cacheOption.hasValue("all") ||
// Cache analysis requires full caching and tracing of cache usage.
cacheAnalyzeEnabled();
return cacheOption.hasValue("all") || cacheAnalyzeEnabled();
}
/**
......@@ -1012,20 +987,6 @@ public class Configuration {
return cacheOption.hasValue("none");
}
/**
* @return {@code true} if cache configuration should be used
*/
public boolean cacheConfig() {
return cacheOption.hasValue("config");
}
/**
* @return {@code true} if implicit caching is used
*/
public boolean cacheImplicit() {
return cacheOption.hasValue("implicit");
}
/**
* @return {@code true} if incremental evaluation is enabled
*/
......@@ -1046,9 +1007,7 @@ public class Configuration {
public boolean incrementalLevelAttr() {
// No chosen level means default -- "attr".
return incrementalOption.hasValue("attr")
|| (!incrementalLevelNode()
&& !incrementalLevelParam()
&& !incrementalLevelRegion());
|| (!incrementalLevelNode() && !incrementalLevelParam() && !incrementalLevelRegion());
}
/**
......@@ -1069,9 +1028,8 @@ public class Configuration {
* @return {@code true} if --incremental=flush
*/
public boolean incrementalChangeFlush() {
return incrementalOption.hasValue("flush") ||
// No chosen strategy means default -- "flush".
!incrementalChangeMark();
return incrementalOption.hasValue("flush") || !incrementalChangeMark();
}
/**
......
......@@ -46,6 +46,7 @@ import java.util.Scanner;
import org.jastadd.ast.AST.ASTDecl;
import org.jastadd.ast.AST.Ast;
import org.jastadd.ast.AST.CacheDecl;
import org.jastadd.ast.AST.Component;
import org.jastadd.ast.AST.Grammar;
import org.jastadd.ast.AST.InhDecl;
......@@ -193,7 +194,7 @@ public class JastAdd {
return 1;
}
if (checkErrors("reading cache files", readCacheFiles(grammar), err)) {
if (checkErrors("cache configuration", applyCacheConfiguration(grammar), err)) {
return 1;
}
......@@ -381,6 +382,29 @@ public class JastAdd {
return problems;
}
protected static Collection<Problem> applyCacheConfiguration(Grammar grammar) {
Collection<Problem> problems = new LinkedList<Problem>();
for (int i = 0; i < grammar.cacheDecls.size(); ++i) {
CacheDecl decl = grammar.cacheDecls.get(i);
for (int j = 0; j < i; ++j) {
CacheDecl prev = grammar.cacheDecls.get(j);
if (decl.signature.equals(prev.signature) && !decl.mode.equals(prev.mode)) {
problems.add(Problem.builder()
.message("conflicting cache declaration for attribute %s.%s, "
+ "previous declaration is at %s:%d", decl.hostName, decl.attrName,
prev.fileName, prev.startLine)
.sourceFile(decl.fileName)
.sourceLine(decl.startLine)
.buildError());
break;
}
}
grammar.applyCacheMode(decl, problems);
}
grammar.cacheDecls.clear();
return problems;
}
/** Add synthesized NTAs as components in their host types. */
private Collection<Problem> addNtaComponents(Grammar grammar) {
Collection<Problem> problems = new LinkedList<Problem>();
......@@ -397,19 +421,6 @@ public class JastAdd {
return problems;
}
private Collection<Problem> readCacheFiles(Grammar grammar) {
Collection<Problem> problems = new LinkedList<Problem>();
if (!(config.cacheConfig() || config.cacheImplicit())) {
return problems;
}
for (Iterator<String> iter = config.getCacheFiles().iterator(); iter.hasNext();) {
String fileName = iter.next();
File cacheFile = new File(fileName);
parseCacheDeclarations(cacheFile, grammar, problems);
}
return problems;
}
/**
* Inject aspect and attribute definitions.
*/
......@@ -439,8 +450,7 @@ public class JastAdd {
return allProblems;
}
private void genCacheAnalyzer(Grammar grammar)
throws FileNotFoundException {
private void genCacheAnalyzer(Grammar grammar) throws FileNotFoundException {
grammar.createPackageOutputDirectory();
PrintWriter writer = new PrintWriter(grammar.targetJavaFile("CacheAnalyzer"));
grammar.emitCacheAnalyzer(writer);
......@@ -610,40 +620,6 @@ public class JastAdd {
return problems;
}
/**
* Read the cache declarations from a cache config file.
*/
protected static void parseCacheDeclarations(File source, Grammar grammar,
Collection<Problem> problems) {
Reader inStream = null;
String fileName = source.getName();
try {
inStream = new FileReader(source);
JragParser jp = new JragParser(inStream);
jp.root = grammar;
jp.setFileName(fileName);
jp.CacheDeclarations();
} catch (org.jastadd.jrag.AST.ParseException e) {
problems.add(Problem.builder()
.message("syntax error")
.sourceFile(fileName)
.sourceLine(e.currentToken.next.beginLine)
.sourceColumn(e.currentToken.next.beginColumn)
.buildError());
} catch (FileNotFoundException e) {
problems.add(Problem.builder()
.message("could not find cache file '%s'", fileName)
.buildError());
} finally {
if (inStream != null)
try {
inStream.close();
} catch (IOException e) {
// Failed to close input. Not a problem.
}
}
}
/**
* Reads the line containing a syntax error, and adds highlighting characters under the line.
*/
......
/* Copyright (c) 2016, Jesper Öqvist <jesper.oqvist@cs.lth.se>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Lund University nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jastadd.ast.AST;
public enum CacheMode {
/** Implicit cache beahviour. */
DEFAULT,
/** Attribute is declared lazy. */
LAZY,
/** Declared cached using a cache declaration. */
CACHED,
/** Declared uncached using a cache declaration. */
UNCACHED,
}
......@@ -34,7 +34,7 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
* method declarator) not throws declarations or method body.
*/
public static void unparseAbstract(ASTAspectMethodDeclaration self, StringBuffer buf) {
// Remove optional "Class." before IdDecl in method declaration
// Remove optional "Class." before IdDecl in method declaration.
for (int i = 0; i < self.jjtGetNumChildren(); ++i) {
SimpleNode n = (SimpleNode) self.jjtGetChild(i);
if (n instanceof ASTMethodDeclarator) {
......@@ -215,7 +215,7 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
node = node.jjtGetParent();
}
if(node instanceof ASTCompilationUnit || node == null) {
// skip the "<ASTNode>." part
// Skip the "<ASTNode>." part.
Token t1 = ((SimpleNode) self.jjtGetChild(0)).lastToken;
Token t2 = ((SimpleNode) self.jjtGetChild(1)).firstToken;
Token t = new Token();
......@@ -231,7 +231,7 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
}
public Object visit(ASTAspectConstructorDeclaration self, Object data) {
StringBuffer buf = (StringBuffer) data;
// Ditch the comment, if one exists
// Ditch the comment, if one exists.
self.firstToken.specialToken = null;
// ConstructorDeclaration <- ClassBodyDeclaration <-
......@@ -241,23 +241,23 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
node = node.jjtGetParent();
}
if (node instanceof ASTCompilationUnit || node == null) {
// skip the "<ASTNode>." part
// Skip the "<ASTNode>." part.
Token t1 = ((SimpleNode) self.jjtGetChild(0)).firstToken;
Token t2 = self.firstToken;
while(t2.next.next.next != t1)
while (t2.next.next.next != t1) {
t2 = t2.next;
}
t2.image ="";
t2.next.image="";
Unparser.unparseSimple(new Unparser(), self, buf);
}
else {
} else {
unparseSimple(self, buf);
}
return null;
}
public Object visit(ASTAspectRefineConstructorDeclaration self, Object data) {
StringBuffer buf = (StringBuffer) data;
// Ditch the comment, if one exists
// Ditch the comment, if one exists.
self.firstToken.specialToken = null;
// ConstructorDeclaration <- ClassBodyDeclaration <-
......@@ -269,13 +269,13 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
if (node instanceof ASTCompilationUnit || node == null) {
Token t1 = ((SimpleNode) self.jjtGetChild(0)).firstToken;
Token t2 = self.firstToken;
while(t2.next.next.next != t1)
while(t2.next.next.next != t1) {
t2 = t2.next;
}
t2.image ="";
t2.next.image="";
Unparser.unparseSimple(new Unparser(), self, buf);
}
else {
} else {
unparseSimple(self, buf);
}
return null;
......@@ -285,7 +285,7 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
}
public Object visit(ASTAspectFieldDeclaration self, Object data) {
StringBuffer buf = (StringBuffer) data;
// Ditch the comment, if one exists
// Ditch the comment, if one exists.
self.firstToken.specialToken = null;
// FieldDeclaration <- ClassBodyDeclaration <-
......@@ -295,7 +295,7 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
node = node.jjtGetParent();
}
if (node instanceof ASTCompilationUnit || node == null) {
// skip the "<ASTNode>." part
// Skip the "<ASTNode>." part.
Token t1 = ((SimpleNode) self.jjtGetChild(0)).lastToken;
Token t2 = ((SimpleNode) self.jjtGetChild(1)).firstToken;
Token t = new Token();
......@@ -303,8 +303,7 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
t2.specialToken = t;
t1.next = t2;
Unparser.unparseSimple(new Unparser(), self, buf);
}
else {
} else {
unparseSimple(self, buf);
}
return null;
......@@ -389,7 +388,7 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
}
public Object visit(ASTFieldDeclaration self, Object data) {
StringBuffer buf = (StringBuffer) data;
// Ditch the comment, if one exists
// Ditch the comment, if one exists.
//self.firstToken.specialToken = null;
// FieldDeclaration <- ClassBodyDeclaration <-
......@@ -399,7 +398,7 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
node = node.jjtGetParent();
}
if (node instanceof ASTCompilationUnit) {
// skip the "<ASTNode>." part
// Skip the "<ASTNode>." part.
Token t1 = ((SimpleNode) self.jjtGetChild(0)).lastToken;
Token t2 = ((SimpleNode) self.jjtGetChild(1)).firstToken;
Token t = new Token();
......@@ -407,8 +406,7 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
t2.specialToken = t;
t1.next = t2;
Unparser.unparseSimple(new Unparser(), self, buf);
}
else {
} else {
unparseSimple(self, buf);
}
return null;
......@@ -427,7 +425,7 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
}
public Object visit(ASTMethodDeclaration self, Object data) {
StringBuffer buf = (StringBuffer) data;
// Ditch the comment, if one exists
// Ditch the comment, if one exists.
//self.firstToken.specialToken = null;
// MethodDeclaration <- ClassBodyDeclaration <-
......@@ -438,7 +436,7 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
node = node.jjtGetParent();
}
if (node instanceof ASTCompilationUnit) {
// skip the "<ASTNode>." part
// Skip the "<ASTNode>." part.
Token t1 = ((SimpleNode) self.jjtGetChild(0)).lastToken;
Token t2 = ((SimpleNode) self.jjtGetChild(1)).firstToken;
Token t = new Token();
......@@ -446,8 +444,7 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
t2.specialToken = t;
t1.next = t2;
Unparser.unparseSimple(new Unparser(), self, buf);
}
else {
} else {
unparseSimple(self, buf);
}
return null;
......@@ -725,7 +722,7 @@ public class ClassBodyDeclUnparser implements JragParserVisitor {
public Object visit(ASTDefaultValue self, Object data) {
return unparseSimple(self, (StringBuffer) data);
}
public Object visit(ASTCacheDeclarations self, Object data) {
public Object visit(ASTAspectCacheDeclaration self, Object data) {
return unparseSimple(self, (StringBuffer) data);
}
}
......@@ -19,7 +19,8 @@ public class ClassBodyObject {
public String modifiers = "";
public String aspectName;
public ClassBodyObject(SimpleNode node, String fileName, int line, String comments, String aspectName) {
public ClassBodyObject(SimpleNode node, String fileName, int line, String comments,
String aspectName) {
this.fileName = fileName;
this.line = line;
this.node = node;
......@@ -39,19 +40,27 @@ public class ClassBodyObject {
return s;
}
public String getFileName() { return fileName; }
public int getStartLine() { return line; }
public String getFileName() {
return fileName;
}
public int getStartLine() {
return line;
}
public String getAspectName() { return aspectName; }
public String getAspectName() {
return aspectName;
}
public String legacyAspectName() {
String name = fileName;
if(name.endsWith(".jrag"))
if (name.endsWith(".jrag")) {
name = name.substring(0, name.length() - 5);
else if(name.endsWith(".jadd"))
} else if (name.endsWith(".jadd")) {
name = name.substring(0, name.length() - 5);
else if(name.endsWith(".ast"))
} else if (name.endsWith(".ast")) {
name = name.substring(0, name.length() - 4);
}
String pattern = File.separator.equals("\\") ? pattern = "\\\\" : File.separator;
String[] names = name.split(pattern);
return names[names.length-1];
......@@ -62,9 +71,10 @@ public class ClassBodyObject {
}
public String modifiers() {
if (modifiers.isEmpty())
if (modifiers.isEmpty()) {
return "";
else
} else {
return modifiers + " ";
}
}
}
......@@ -639,7 +639,9 @@ void AspectBodyDeclaration() :
|
LOOKAHEAD( AspectFieldDeclarationLookahead() )
AspectFieldDeclaration()
|
LOOKAHEAD( ( "cache" | "uncache" ) )
AspectCacheDeclaration()
}
/**
......@@ -784,8 +786,7 @@ void AspectInterfaceSynAttributeDeclaration() :
";" { last = token; }
{
root.addSynDecl(attrName.image, attrType, className,
(root.config().cacheImplicit() || isLazy),
fileName, first.beginLine, last.endLine, list,
isLazy, fileName, first.beginLine, last.endLine, list,
bottomValue == null ? "" : Unparser.unparse(bottomValue),
isFinal, false, jjtThis, enclosingAspect, annotations);
......@@ -831,7 +832,7 @@ void AspectInterfaceInhAttributeDeclaration() :
{
last = token;
root.addInhDecl(attrName.image, attrType, className,
(root.config().cacheImplicit() || isLazy), fileName, first.beginLine,
isLazy, fileName, first.beginLine,
last.endLine, list, bottomValue == null ? "" : Unparser.unparse(bottomValue),
isFinal, false, jjtThis, enclosingAspect, annotations);
}
......@@ -1050,7 +1051,7 @@ void AspectSynAttributeDeclaration() :
{
root.addSynDecl(attrName.image, attrType, targetName,
(root.config().cacheImplicit() || isLazy), fileName, first.beginLine,
isLazy, fileName, first.beginLine,
last.endLine, list, bottomValue == null ? "" : Unparser.unparse(bottomValue),
isFinal, isNTA, jjtThis, enclosingAspect, annotations);
......@@ -1103,7 +1104,7 @@ void AspectInhAttributeDeclaration() :
{
last = token;
root.addInhDecl(attrName.image, attrType, targetName,
(root.config().cacheImplicit() || isLazy), fileName, first.beginLine,
isLazy, fileName, first.beginLine,
last.endLine, list, bottomValue == null ? "" : Unparser.unparse(bottomValue),
isFinal, isNTA, jjtThis, enclosingAspect, annotations);
}
......@@ -2589,8 +2590,8 @@ void DefaultValue():
}
// Adding (cache|uncached) keywords in front of each line in the cache configuration.
// This information is propagated to the grammar via setAttrDeclLazy(..)
void CacheDeclarations():
// This information is propagated to the grammar via setAttributeCacheMode(..)
void AspectCacheDeclaration():
{
Token t;
Token cacheConfig;
......@@ -2602,7 +2603,6 @@ void CacheDeclarations():
org.jastadd.ast.AST.List paramList = new org.jastadd.ast.AST.List();
}
{
(
( cacheConfig = "cache" | cacheConfig = "uncache" )
hostType = <IDENTIFIER> "."
attrName = AttributeName()
......@@ -2618,10 +2618,9 @@ void CacheDeclarations():
")"
";"
{
root.setAttrDeclLazy(cacheConfig.image, hostType.image, attrName.image,
root.setAttributeCacheMode(cacheConfig.image, hostType.image, attrName.image,
paramList, fileName, cacheConfig.beginLine);
}
)*
}
// Valid Java identifiers include 'syn', 'eq', etc. (reserved JastAdd words are legal in pure Java)
......
......@@ -475,7 +475,7 @@ public class SignatureUnparser implements JragParserVisitor {
public Object visit(ASTDefaultValue node, Object data) {
return "";
}
public Object visit(ASTCacheDeclarations node, Object data) {
public Object visit(ASTAspectCacheDeclaration node, Object data) {
return "";
}
}
......@@ -200,7 +200,7 @@ public class Unparser implements JragParserVisitor {
node = node.jjtGetParent();
}
if (node instanceof ASTCompilationUnit || node == null) {
// Remove optional "Class." before IdDecl in method declaration
// Remove optional "Class." before IdDecl in method declaration.
for (int i = 0; i < self.jjtGetNumChildren(); ++i) {
SimpleNode n = (SimpleNode) self.jjtGetChild(i);
if (n instanceof ASTMethodDeclarator) {
......@@ -421,7 +421,7 @@ public class Unparser implements JragParserVisitor {
node = node.jjtGetParent();
}
if(node instanceof ASTCompilationUnit) {
// Remove optional "Class." before IdDecl in method declaration
// Remove optional "Class." before IdDecl in method declaration.
Token t1 = ((SimpleNode) self.jjtGetChild(0)).lastToken;
Token t2 = ((SimpleNode) self.jjtGetChild(1)).firstToken;
Token t = new Token();
......@@ -796,7 +796,7 @@ public class Unparser implements JragParserVisitor {
Unparser.unparseSimple(this, self, (StringBuffer) data);
return null;
}
public Object visit(ASTCacheDeclarations self, Object data) {
public Object visit(ASTAspectCacheDeclaration self, Object data) {
Unparser.unparseSimple(this, self, (StringBuffer) data);
return null;
}
......
......@@ -26,13 +26,12 @@
# POSSIBILITY OF SUCH DAMAGE.
# Code for inner class CacheAnalyzer
CacheAnalyzer = [[
CacheAnalyzer [[
/**
* Cache analyzer based on the ideas presented in
*
* <a href="http://dx.doi.org/10.1007/978-3-642-19440-5_2">
* Automated selective caching for reference attribute grammars"
* </a>
* Automated selective caching for reference attribute grammars</a>
* <i>Emma S&ouml;derberg and G&ouml;rel Hedin</i>
* <i>Dept. of Computer Science, Lund University</i>
*
......@@ -175,9 +174,11 @@ public class CacheAnalyzer extends $StateClass.Trace.InputFilter {
public void printAllMinusOneConfig(java.io.PrintWriter out) {
java.util.Set<String> configSet = getAllSet();
configSet.removeAll(getOneSet());
out.println("aspect CacheConfig {");
for (String attr : configSet) {
out.println(" cache " + attr + ";");
}
out.println("}");
out.flush();
}
......@@ -188,9 +189,11 @@ public class CacheAnalyzer extends $StateClass.Trace.InputFilter {
public void printUsedMinusOneConfig(java.io.PrintWriter out) {
java.util.Set<String> configSet = getUsedSet();
configSet.removeAll(getOneSet());
out.println("aspect CacheConfig {");
for (String attr : configSet) {
out.println(" cache " + attr + ";");
}
out.println("}");
out.flush();
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment