/src/org/ooc/frontend/parser/ClassDeclParser.java
Java | 138 lines | 111 code | 26 blank | 1 comment | 41 complexity | 4ff42f0c77ae2299cbd341e6b6266b28 MD5 | raw file
1package org.ooc.frontend.parser; 2 3import java.util.ArrayList; 4import java.util.List; 5 6import org.ooc.frontend.model.ClassDecl; 7import org.ooc.frontend.model.FunctionDecl; 8import org.ooc.frontend.model.Module; 9import org.ooc.frontend.model.Node; 10import org.ooc.frontend.model.NodeList; 11import org.ooc.frontend.model.OocDocComment; 12import org.ooc.frontend.model.Type; 13import org.ooc.frontend.model.TypeParam; 14import org.ooc.frontend.model.VariableDecl; 15import org.ooc.frontend.model.tokens.Token; 16import org.ooc.frontend.model.tokens.TokenReader; 17import org.ooc.frontend.model.tokens.Token.TokenType; 18import org.ubi.CompilationFailedError; 19import org.ubi.SourceReader; 20 21public class ClassDeclParser { 22 23 @SuppressWarnings("unchecked") 24 public static ClassDecl parse(Module module, SourceReader sReader, TokenReader reader) { 25 int mark = reader.mark(); 26 27 OocDocComment comment = null; 28 if(reader.peek().type == TokenType.OOCDOC) { 29 Token token = reader.read(); 30 comment = new OocDocComment(token.get(sReader), token); 31 // allow an arbitrary number of newlines after the oocdoc comment. 32 while(reader.peek().type == TokenType.LINESEP) { 33 reader.skip(); 34 } 35 } 36 37 String name = ""; 38 Token tName = reader.peek(); 39 if(tName.type != TokenType.NAME) { 40 reader.reset(mark); 41 return null; 42 } 43 44 name = tName.get(sReader); 45 reader.skip(); 46 if(reader.read().type != TokenType.COLON) { 47 reader.reset(mark); 48 return null; 49 } 50 51 boolean isAbstract = reader.peek().type == TokenType.ABSTRACT_KW; 52 if(isAbstract) reader.skip(); 53 List<TypeParam> genTypes = null; 54 55 if(reader.readWhiteless().type == TokenType.CLASS_KW) { 56 57 if(reader.peek().type == TokenType.LESSTHAN) { 58 reader.skip(); 59 genTypes = new ArrayList<TypeParam>(); 60 TypeParamParser.parse(sReader, reader, genTypes); 61 } 62 63 Type superType = null; 64 if(reader.peek().type == TokenType.EXTENDS_KW) { 65 reader.skip(); 66 superType = TypeParser.parse(module, sReader, reader, false); 67 } 68 69 reader.skipWhitespace(); 70 Token t2 = reader.read(); 71 if(t2.type != TokenType.OPEN_BRACK) { 72 throw new CompilationFailedError(sReader.getLocation(t2), 73 "Expected opening bracket to begin class declaration."); 74 } 75 76 if(superType != null && name.equals(superType.getName())) { 77 throw new CompilationFailedError(sReader.getLocation(tName), "A class cannot extends itself!"); 78 } 79 80 ClassDecl classDecl = new ClassDecl(name, superType, isAbstract, module, tName); 81 if(genTypes != null) for(TypeParam genType: genTypes) { 82 classDecl.addTypeParam(genType); 83 } 84 classDecl.addDefaultInit(); 85 module.parseStack.push(classDecl); 86 if(comment != null) classDecl.setComment(comment); 87 88 while(reader.hasNext() && reader.peek().type != TokenType.CLOS_BRACK) { 89 90 if(reader.skipWhitespace()) continue; 91 92 Node candidate = VariableDeclParser.parseMulti(module, sReader, reader); 93 if(candidate != null) { 94 if(candidate instanceof NodeList<?>) { 95 NodeList<VariableDecl> vDecls = (NodeList<VariableDecl>) candidate; 96 for(VariableDecl vDecl : vDecls) { 97 classDecl.addVariable(vDecl); 98 } 99 } else { 100 VariableDecl vDecl = ((VariableDecl) candidate); 101 classDecl.addVariable(vDecl); 102 } 103 Token tok = reader.read(); 104 if(tok.type != TokenType.LINESEP && tok.type != TokenType.OOCDOC) { 105 throw new CompilationFailedError(sReader.getLocation(reader.prev()), 106 "Expected semi-colon after variable declaration in class declaration"); 107 } 108 109 continue; 110 } 111 112 FunctionDecl funcDecl = FunctionDeclParser.parse(module, sReader, reader, false); 113 if(funcDecl != null) { 114 classDecl.addFunction(funcDecl); 115 continue; 116 } 117 118 if(reader.peek().type == TokenType.OOCDOC) { 119 reader.read(); 120 continue; 121 } 122 123 throw new CompilationFailedError(sReader.getLocation(reader.peek()), 124 "Expected variable declaration or function declaration in a class declaration, got "+reader.peek()); 125 126 } 127 reader.skip(); 128 129 module.parseStack.pop(classDecl); 130 return classDecl; 131 132 } 133 134 reader.reset(mark); 135 return null; 136 } 137 138}