PageRenderTime 39ms CodeModel.GetById 23ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/src/org/ooc/frontend/parser/ClassDeclParser.java

http://github.com/nddrylliog/ooc
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}