private ITypeMember parseFieldOrPropertyOrMethod(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers, bool partial, TypeReferenceNode type, int startPosition) { if (!isIdentifier(lexicalUnit)) { throw error(ParseErrorId.IdentifierExpected); } int sp = scanner.StartPosition; int len = getLexicalUnitLength(); saveScannerState(); var typeParameters = new ArrayList<SimpleNameTypeReferenceNode>(); nextLexicalUnit(true); parseTypeParameters(typeParameters); Modifier setterAccess = checkSetterAccess(); bool forceAsField = false; if (lexicalUnit == LexicalUnit.Multiply) { forceAsField = true; nextLexicalUnit(true); } switch (lexicalUnit) { case OpenParenthesis: if (setterAccess != Modifier.Public || forceAsField) { throw error(ParseErrorId.IdentifierExpected); } var methodDeclaration = new MethodDeclarationNode { IsPartial = partial, ReturnType = type, NameOffset = sp, NameLength = len, StartPosition = startPosition }; if (docCommentEndPosition > 0) { methodDeclaration.DocumentationOffset = docCommentStartPosition; methodDeclaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(methodDeclaration); methodDeclaration.Modifiers.addAll(modifiers); methodDeclaration.Annotations.addAll(annotations); foreach (var t in typeParameters) { if (t.TypeReferenceKind != TypeReferenceKind.SimpleName || t.TypeArguments.size() > 0) { throw error(ParseErrorId.SimpleNameExpected); } methodDeclaration.TypeParameters.add((SimpleNameTypeReferenceNode)t); } if (nextLexicalUnit(true) != LexicalUnit.CloseParenthesis) { parseFormalParameters(methodDeclaration.Parameters, LexicalUnit.CloseParenthesis); } else { nextLexicalUnit(true); } parseTypeParameterConstraintsClauses(methodDeclaration.ConstraintsClauses); switch (lexicalUnit) { case OpenBrace: methodDeclaration.Body = parseBlockStatement(); methodDeclaration.EndPosition = methodDeclaration.Body.EndPosition; break; case SemiColon: methodDeclaration.EndPosition = scanner.EndPosition; nextLexicalUnit(true); break; default: throw error(ParseErrorId.OpenBraceExpected); } return methodDeclaration; case OpenBrace: if (setterAccess != Modifier.Public || forceAsField) { throw error(ParseErrorId.IdentifierExpected); } var propertyDeclaration = new PropertyDeclarationNode { Type = type, NameOffset = sp, NameLength = len, StartPosition = startPosition }; if (docCommentEndPosition > 0) { propertyDeclaration.DocumentationOffset = docCommentStartPosition; propertyDeclaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(propertyDeclaration); propertyDeclaration.Modifiers.addAll(modifiers); nextLexicalUnit(true); parseAccessorDeclaration(propertyDeclaration, false); if (lexicalUnit != LexicalUnit.CloseBrace) { parseAccessorDeclaration(propertyDeclaration, false); } docCommentEndPosition = 0; propertyDeclaration.EndPosition = scanner.EndPosition; nextLexicalUnit(false); return propertyDeclaration; case Assign: { if (setterAccess != Modifier.Public || forceAsField) { throw error(ParseErrorId.IdentifierExpected); } var declaration = new FieldDeclarationNode { Type = type, StartPosition = startPosition }; if (docCommentEndPosition > 0) { declaration.DocumentationOffset = docCommentStartPosition; declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(declaration); declaration.Modifiers.addAll(modifiers); declaration.Annotations.addAll(annotations); nextLexicalUnit(true); var decl = new VariableDeclaratorNode { NameOffset = sp, NameLength = len }; setSavedScannerState(decl); decl.Value = parseFieldInitializer(); decl.EndPosition = decl.Value.EndPosition; declaration.Declarators.add(decl); while (lexicalUnit == LexicalUnit.Comma) { if (!isIdentifier(nextLexicalUnit(true))) { throw error(ParseErrorId.IdentifierExpected); } decl = new VariableDeclaratorNode { NameOffset = scanner.StartPosition, NameLength = getLexicalUnitLength() }; setScannerState(decl); decl.EndPosition = scanner.EndPosition; declaration.Declarators.add(decl); if (nextLexicalUnit(true) == LexicalUnit.Assign) { nextLexicalUnit(true); decl.Value = parseFieldInitializer(); decl.EndPosition = decl.Value.EndPosition; } } docCommentEndPosition = 0; declaration.EndPosition = parseSemiColon(false, false); return declaration; } case Comma: { if (setterAccess != Modifier.Public || forceAsField) { throw error(ParseErrorId.IdentifierExpected); } var declaration = new FieldDeclarationNode { Type = type, StartPosition = startPosition }; if (docCommentEndPosition > 0) { declaration.DocumentationOffset = docCommentStartPosition; declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(declaration); declaration.Modifiers.addAll(modifiers); declaration.Annotations.addAll(annotations); var decl = new VariableDeclaratorNode { NameOffset = sp, NameLength = len }; setSavedScannerState(decl); decl.EndPosition = sp + len; declaration.Declarators.add(decl); do { if (!isIdentifier(nextLexicalUnit(true))) { throw error(ParseErrorId.IdentifierExpected); } decl = new VariableDeclaratorNode { NameOffset = scanner.StartPosition, NameLength = getLexicalUnitLength() }; setScannerState(decl); declaration.Declarators.add(decl); decl.EndPosition = scanner.EndPosition; if (nextLexicalUnit(true) == LexicalUnit.Assign) { nextLexicalUnit(true); decl.Value = parseFieldInitializer(); decl.EndPosition = decl.Value.EndPosition; } } while (lexicalUnit == LexicalUnit.Comma); docCommentEndPosition = 0; declaration.EndPosition = parseSemiColon(false, false); return declaration; } case SemiColon: { if ((modifiers.contains(Modifier.Public) || modifiers.contains(Modifier.Protected)) && !forceAsField) { var propertyShortDeclaration = new PropertyDeclarationNode { Type = type, NameOffset = sp, NameLength = len, StartPosition = startPosition }; if (docCommentEndPosition > 0) { propertyShortDeclaration.DocumentationOffset = docCommentStartPosition; propertyShortDeclaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(propertyShortDeclaration); propertyShortDeclaration.Modifiers.addAll(modifiers); fakeParseShortProperty(propertyShortDeclaration, setterAccess, false); docCommentEndPosition = 0; propertyShortDeclaration.EndPosition = scanner.EndPosition; nextLexicalUnit(false); return propertyShortDeclaration; } var declaration = new FieldDeclarationNode { Type = type, StartPosition = startPosition }; if (docCommentEndPosition > 0) { declaration.DocumentationOffset = docCommentStartPosition; declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(declaration); declaration.Modifiers.addAll(modifiers); declaration.Annotations.addAll(annotations); var decl = new VariableDeclaratorNode { NameOffset = sp, NameLength = len }; setSavedScannerState(decl); decl.EndPosition = sp + len; declaration.Declarators.add(decl); docCommentEndPosition = 0; declaration.EndPosition = scanner.EndPosition; nextLexicalUnit(false); return declaration; } default: throw error(ParseErrorId.UnexpectedLexicalUnit); } }
private LocalDeclarationStatementNode parseLocalDeclarationStatement(TypeReferenceNode type, bool eatSemiColon) { var declaration = new LocalDeclarationStatementNode(); setSavedScannerState(declaration); declaration.Type = type; var declarator = new VariableDeclaratorNode(); setScannerState(declarator); declarator.NameOffset = scanner.StartPosition; declarator.NameLength = getLexicalUnitLength(); declaration.Declarators.add(declarator); nextLexicalUnit(true); if (lexicalUnit == LexicalUnit.Assign) { nextLexicalUnit(true); declarator.Value = parseLocalVariableInitializer(); declarator.EndPosition = declarator.Value.EndPosition; } else { declarator.EndPosition = declarator.NameOffset + declarator.NameLength; } int endPosition = declarator.EndPosition; while (lexicalUnit == LexicalUnit.Comma) { if (!isIdentifier(nextLexicalUnit(true))) { throw error(ParseErrorId.IdentifierExpected); } declarator = new VariableDeclaratorNode(); setScannerState(declarator); declarator.NameOffset = scanner.StartPosition; declarator.NameLength = getLexicalUnitLength(); declaration.Declarators.add(declarator); nextLexicalUnit(true); if (lexicalUnit == LexicalUnit.Assign) { nextLexicalUnit(true); declarator.Value = parseLocalVariableInitializer(); declarator.EndPosition = declarator.Value.EndPosition; } else { declarator.EndPosition = declarator.NameOffset + declarator.NameLength; } endPosition = declarator.EndPosition; } if (eatSemiColon) { declaration.EndPosition = parseSemiColon(false, false); } else { declaration.EndPosition = endPosition; } return declaration; }
private String typeReferenceToString(TypeReferenceNode typeRef) { var sb = new StringBuilder(); switch (typeRef.TypeReferenceKind) { case Int: case Long: case Short: case Float: case Double: case Boolean: case Byte: case Void: case String: sb.append(typeRef.TypeReferenceKind.toString().toLowerCase()); break; case SimpleName: var simpleName = (SimpleNameTypeReferenceNode)typeRef; sb.append(new String(text, simpleName.NameOffset, simpleName.NameLength)); if (simpleName.TypeArguments.size() > 0) { formatTypeArguments(simpleName.TypeArguments, sb); } break; case Qualified: var qtype = (QualifiedTypeReferenceNode)typeRef; sb.append(typeReferenceToString(qtype.EnclosingType)); sb.append("."); sb.append(typeReferenceToString(qtype.SimpleName)); break; case Array: var array = (ArrayTypeReferenceNode)typeRef; sb.append(typeReferenceToString(array.ElementType)); sb.append("[]"); break; default: throw new RuntimeException("Unhandled type kind: " + typeRef.TypeReferenceKind); } return sb.toString(); }
private IndexerDeclarationNode parseIndexerDeclaration(List<AnnotationSectionNode> annotations, EnumSet<Modifier> modifiers, bool partial, TypeReferenceNode type, bool inInterface, int startPosition) { var declaration = new IndexerDeclarationNode { Type = type, StartPosition = startPosition }; if (docCommentEndPosition > 0) { declaration.DocumentationOffset = docCommentStartPosition; declaration.DocumentationLength = docCommentEndPosition - docCommentStartPosition; docCommentEndPosition = 0; } setSavedScannerState(declaration); declaration.Modifiers.addAll(modifiers); declaration.Annotations.addAll(annotations); if (lexicalUnit != LexicalUnit.OpenBracket) { throw error(ParseErrorId.OpenBracketExpected); } if (nextLexicalUnit(true) != LexicalUnit.CloseBracket) { parseFormalParameters(declaration.Parameters, LexicalUnit.CloseBracket); } else { nextLexicalUnit(true); } Modifier setterAccess = Modifier.Public; if (lexicalUnit == LexicalUnit.Xor) { if (!inInterface) { throw error(ParseErrorId.OpenBraceExpected); } setterAccess = Modifier.Private; nextLexicalUnit(true); } if (lexicalUnit == LexicalUnit.SemiColon) { if (!inInterface) { throw error(ParseErrorId.OpenBraceExpected); } fakeParseShortProperty(declaration, setterAccess, inInterface); docCommentEndPosition = 0; declaration.EndPosition = scanner.EndPosition; nextLexicalUnit(false); return declaration; } if (lexicalUnit != LexicalUnit.OpenBrace) { throw error(ParseErrorId.OpenBraceExpected); } nextLexicalUnit(true); parseAccessorDeclaration(declaration, inInterface); if (lexicalUnit != LexicalUnit.CloseBrace) { parseAccessorDeclaration(declaration, inInterface); } docCommentEndPosition = 0; declaration.EndPosition = scanner.EndPosition; nextLexicalUnit(false); return declaration; }
private void print(TypeReferenceNode typeReference, StringBuilder sb) { switch (typeReference.TypeReferenceKind) { case Int: case Char: case Long: case Short: case Float: case Double: case Boolean: case Byte: case Void: case String: sb.append(typeReference.TypeReferenceKind.toString().toLowerCase()); break; case SimpleName: var simpleName = (SimpleNameTypeReferenceNode)typeReference; sb.append(new String(text, simpleName.NameOffset, simpleName.NameLength)); if (simpleName.TypeArguments.size() > 0) { print(simpleName.TypeArguments, sb); } break; case Qualified: var qtype = (QualifiedTypeReferenceNode)typeReference; print(qtype.EnclosingType, sb); sb.append("."); print(qtype.SimpleName, sb); break; case Array: var array = (ArrayTypeReferenceNode)typeReference; print(array.ElementType, sb); sb.append("[]"); break; case Wildcard: sb.append("?"); break; case LowerBoundedWildcard: var wildcard = (WildcardTypeReferenceNode)typeReference; print(wildcard.Bound, sb); sb.append(" : ?"); break; case UpperBoundedWildcard: wildcard = (WildcardTypeReferenceNode)typeReference; sb.append("? : "); print(wildcard.Bound, sb); break; default: throw new RuntimeException("Unhandled type kind: " + typeReference.TypeReferenceKind); } }