001 /* 002 * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered 003 * by the modified BSD License. You should have received a copy of the 004 * modified BSD license with this compiler. 005 * 006 * Copyright (c) 2005-2008, Torbjorn Ekman 007 * All rights reserved. 008 */ 009 010 aspect ErrorCheck { 011 012 protected String ASTNode.sourceFile() { 013 ASTNode node = this; 014 while(node != null && !(node instanceof CompilationUnit)) 015 node = node.getParent(); 016 if(node == null) 017 return "Unknown file"; 018 CompilationUnit u = (CompilationUnit)node; 019 return u.relativeName(); 020 } 021 022 syn int ASTNode.lineNumber() { 023 ASTNode n = this; 024 while(n.getParent() != null && n.getStart() == 0) { 025 n = n.getParent(); 026 } 027 return getLine(n.getStart()); 028 } 029 030 eq ClassDecl.lineNumber() = getLine(IDstart); 031 eq MethodDecl.lineNumber() = getLine(IDstart); 032 033 // set start and end position to the same as the argument and return self 034 public ASTNode ASTNode.setLocation(ASTNode node) { 035 setStart(node.getStart()); 036 setEnd(node.getEnd()); 037 return this; 038 } 039 040 public ASTNode ASTNode.setStart(int i) { 041 start = i; 042 return this; 043 } 044 public int ASTNode.start() { 045 return start; 046 } 047 public ASTNode ASTNode.setEnd(int i) { 048 end = i; 049 return this; 050 } 051 public int ASTNode.end() { 052 return end; 053 } 054 055 public String ASTNode.location() { 056 return "" + lineNumber(); 057 } 058 public String ASTNode.errorPrefix() { 059 return sourceFile() + ":" + location() + ":\n" + " *** Semantic Error: "; 060 } 061 public String ASTNode.warningPrefix() { 062 return sourceFile() + ":" + location() + ":\n" + " *** WARNING: "; 063 } 064 065 protected java.util.ArrayList CompilationUnit.errors = new java.util.ArrayList(); 066 protected java.util.ArrayList CompilationUnit.warnings = new java.util.ArrayList(); 067 068 public Collection CompilationUnit.parseErrors() { return parseErrors; } 069 public void CompilationUnit.addParseError(Problem msg) { parseErrors.add(msg); } 070 protected Collection CompilationUnit.parseErrors = new ArrayList(); 071 072 class Problem implements Comparable { 073 public int compareTo(Object o) { 074 if(o instanceof Problem) { 075 Problem other = (Problem)o; 076 if(!fileName.equals(other.fileName)) 077 return fileName.compareTo(other.fileName); 078 if(line != other.line) 079 return line - other.line; 080 return message.compareTo(other.message); 081 } 082 return 0; 083 } 084 public static class Severity { 085 public static final Severity ERROR = new Severity(); 086 public static final Severity WARNING = new Severity(); 087 private Severity() { } 088 } 089 public static class Kind { 090 public static final Kind OTHER = new Kind(); 091 public static final Kind LEXICAL = new Kind(); 092 public static final Kind SYNTACTIC = new Kind(); 093 public static final Kind SEMANTIC = new Kind(); 094 private Kind() { } 095 } 096 protected int line = -1; 097 public int line() { return line; } 098 protected int column = -1; 099 public int column() { return column; } 100 protected int endLine = -1; 101 public int endLine() { return endLine; } 102 protected int endColumn = -1; 103 public int endColumn() { return endColumn; } 104 protected String fileName; 105 public String fileName() { return fileName; } 106 public void setFileName(String fileName) { this.fileName = fileName; } 107 protected String message; 108 public String message() { return message; } 109 protected Severity severity = Severity.ERROR; 110 public Severity severity() { return severity; } 111 protected Kind kind = Kind.OTHER; 112 public Kind kind() { return kind; } 113 public Problem(String fileName, String message) { 114 this.fileName = fileName; 115 this.message = message; 116 } 117 public Problem(String fileName, String message, int line) { 118 this(fileName, message); 119 this.line = line; 120 } 121 public Problem(String fileName, String message, int line, Severity severity) { 122 this(fileName, message); 123 this.line = line; 124 this.severity = severity; 125 } 126 public Problem(String fileName, String message, int line, int column, Severity severity) { 127 this(fileName, message); 128 this.line = line; 129 this.column = column; 130 this.severity = severity; 131 } 132 public Problem(String fileName, String message, int line, Severity severity, Kind kind) { 133 this(fileName, message); 134 this.line = line; 135 this.kind = kind; 136 this.severity = severity; 137 } 138 public Problem(String fileName, String message, int line, int column, Severity severity, Kind kind) { 139 this(fileName, message); 140 this.line = line; 141 this.column = column; 142 this.kind = kind; 143 this.severity = severity; 144 } 145 public Problem(String fileName, String message, int line, int column, int endLine, int endColumn, Severity severity, Kind kind) { 146 this(fileName, message); 147 this.line = line; 148 this.column = column; 149 this.endLine = endLine; 150 this.endColumn = endColumn; 151 this.kind = kind; 152 this.severity = severity; 153 } 154 public String toString() { 155 String location = ""; 156 if(line != -1 && column != -1) 157 location = line + "," + column + ":"; 158 else if(line != -1) 159 location = line + ":"; 160 String s = ""; 161 if(this.kind == Kind.LEXICAL) 162 s = "Lexical Error: "; 163 else if(this.kind == Kind.SYNTACTIC) 164 s = "Syntactic Error: "; 165 else if(this.kind == Kind.SEMANTIC) 166 s = "Semantic Error: "; 167 return fileName + ":" + location + "\n" + " " + s + message; 168 } 169 } 170 171 public void ASTNode.error(String s) { 172 ASTNode node = this; 173 while(node != null && !(node instanceof CompilationUnit)) 174 node = node.getParent(); 175 CompilationUnit cu = (CompilationUnit)node; 176 if(getNumChild() == 0 && getStart() != 0 && getEnd() != 0) { 177 int line = getLine(getStart()); 178 int column = getColumn(getStart()); 179 int endLine = getLine(getEnd()); 180 int endColumn = getColumn(getEnd()); 181 cu.errors.add(new Problem(sourceFile(), s, line, column, endLine, endColumn, Problem.Severity.ERROR, Problem.Kind.SEMANTIC)); 182 } 183 else 184 cu.errors.add(new Problem(sourceFile(), s, lineNumber(), Problem.Severity.ERROR, Problem.Kind.SEMANTIC)); 185 } 186 187 public void ASTNode.warning(String s) { 188 ASTNode node = this; 189 while(node != null && !(node instanceof CompilationUnit)) 190 node = node.getParent(); 191 CompilationUnit cu = (CompilationUnit)node; 192 cu.warnings.add(new Problem(sourceFile(), "WARNING: " + s, lineNumber(), Problem.Severity.WARNING)); 193 } 194 195 public void ASTNode.collectErrors() { 196 nameCheck(); 197 typeCheck(); 198 accessControl(); 199 exceptionHandling(); 200 checkUnreachableStmt(); 201 definiteAssignment(); 202 checkModifiers(); 203 for(int i = 0; i < getNumChild(); i++) { 204 getChild(i).collectErrors(); 205 } 206 } 207 208 public void Program.errorCheck(Collection collection) { 209 for(Iterator iter = compilationUnitIterator(); iter.hasNext(); ) { 210 CompilationUnit cu = (CompilationUnit)iter.next(); 211 if(cu.fromSource()) { 212 cu.collectErrors(); 213 collection.addAll(cu.errors); 214 } 215 } 216 } 217 public void Program.errorCheck(Collection collection, Collection warn) { 218 for(Iterator iter = compilationUnitIterator(); iter.hasNext(); ) { 219 CompilationUnit cu = (CompilationUnit)iter.next(); 220 if(cu.fromSource()) { 221 cu.collectErrors(); 222 collection.addAll(cu.errors); 223 warn.addAll(cu.warnings); 224 } 225 } 226 } 227 228 public void CompilationUnit.errorCheck(Collection collection) { 229 collectErrors(); 230 collection.addAll(errors); 231 } 232 public void CompilationUnit.errorCheck(Collection err, Collection warn) { 233 collectErrors(); 234 err.addAll(errors); 235 warn.addAll(warnings); 236 } 237 238 public boolean Program.errorCheck() { 239 Collection collection = new LinkedList(); 240 errorCheck(collection); 241 if(collection.isEmpty()) 242 return false; 243 System.out.println("Errors:"); 244 for(Iterator iter = collection.iterator(); iter.hasNext(); ) { 245 String s = (String)iter.next(); 246 System.out.println(s); 247 } 248 return true; 249 } 250 }