/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

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