/** * TypeNameAnnotation := TypeName | '{' TypeName '}' */ private Node parseTypeNameAnnotation(JsDocToken token) { if (token == JsDocToken.LEFT_CURLY) { skipEOLs(); Node typeNode = parseTypeName(next()); if (typeNode != null) { skipEOLs(); if (!match(JsDocToken.RIGHT_CURLY)) { reportTypeSyntaxWarning("msg.jsdoc.missing.rc"); } else { next(); } } return typeNode; } else { return parseTypeName(token); } }
/** * TypeNameAnnotation := TypeName | '{' TypeName '}' */ private Node parseTypeNameAnnotation(JsDocToken token) { if (token == JsDocToken.LEFT_CURLY) { skipEOLs(); Node typeNode = parseTypeName(next()); if (typeNode != null) { skipEOLs(); if (!match(JsDocToken.RIGHT_CURLY)) { reportTypeSyntaxWarning("msg.jsdoc.missing.rc"); } else { next(); } } return typeNode; } else { return parseTypeName(token); } }
/** * ParamTypeExpressionAnnotation := '{' ParamTypeExpression '}' */ private Node parseParamTypeExpressionAnnotation(JsDocToken token) { Preconditions.checkArgument(token == JsDocToken.LEFT_CURLY); skipEOLs(); Node typeNode = parseParamTypeExpression(next()); if (typeNode != null) { if (!match(JsDocToken.RIGHT_CURLY)) { reportTypeSyntaxWarning("msg.jsdoc.missing.rc"); } else { next(); } } return typeNode; }
/** * ParamTypeExpressionAnnotation := '{' ParamTypeExpression '}' */ private Node parseParamTypeExpressionAnnotation(JsDocToken token) { checkArgument(token == JsDocToken.LEFT_CURLY); skipEOLs(); Node typeNode = parseParamTypeExpression(next()); if (typeNode != null) { if (!match(JsDocToken.RIGHT_CURLY)) { reportTypeSyntaxWarning("msg.jsdoc.missing.rc"); } else { next(); } } return typeNode; }
/** * ResultType := <empty> | ':' void | ':' TypeExpression */ private Node parseResultType() { skipEOLs(); if (!match(JsDocToken.COLON)) { return newNode(Token.EMPTY); } next(); skipEOLs(); if (match(JsDocToken.STRING) && "void".equals(stream.getString())) { next(); return newNode(Token.VOID); } else { return parseTypeExpression(next()); } }
/** * ResultType := <empty> | ':' void | ':' TypeExpression */ private Node parseResultType() { skipEOLs(); if (!match(JsDocToken.COLON)) { return newNode(Token.EMPTY); } next(); skipEOLs(); if (match(JsDocToken.STRING) && "void".equals(stream.getString())) { next(); return newNode(Token.VOID); } else { return parseTypeExpression(next()); } }
/** * TypeExpressionAnnotation := TypeExpression | * '{' TopLevelTypeExpression '}' */ private Node parseTypeExpressionAnnotation(JsDocToken token) { if (token == JsDocToken.LEFT_CURLY) { skipEOLs(); Node typeNode = parseTopLevelTypeExpression(next()); if (typeNode != null) { skipEOLs(); if (!match(JsDocToken.RIGHT_CURLY)) { reportTypeSyntaxWarning("msg.jsdoc.missing.rc"); } else { next(); } } return typeNode; } else { // TODO(tbreisacher): Add a SuggestedFix for this warning. reportTypeSyntaxWarning("msg.jsdoc.missing.braces"); return parseTypeExpression(token); } }
/** * TypeExpressionAnnotation := TypeExpression | * '{' TopLevelTypeExpression '}' */ private Node parseTypeExpressionAnnotation(JsDocToken token) { if (token == JsDocToken.LEFT_CURLY) { skipEOLs(); Node typeNode = parseTopLevelTypeExpression(next()); if (typeNode != null) { skipEOLs(); if (!match(JsDocToken.RIGHT_CURLY)) { reportTypeSyntaxWarning("msg.jsdoc.missing.rc"); } else { next(); } } return typeNode; } else { // TODO(tbreisacher): Add a SuggestedFix for this warning. reportTypeSyntaxWarning("msg.jsdoc.missing.braces"); return parseTypeExpression(token); } }
private Node parseNameExpression(JsDocToken token) { if (token != JsDocToken.STRING) { return reportGenericTypeSyntaxWarning(); } String typeName = stream.getString(); int lineno = stream.getLineno(); int charno = stream.getCharno(); while (match(JsDocToken.EOL) && typeName.charAt(typeName.length() - 1) == '.') { skipEOLs(); if (match(JsDocToken.STRING)) { next(); typeName += stream.getString(); } } return newStringNode(typeName, lineno, charno); }
/** * FieldType := FieldName | FieldName ':' TypeExpression */ private Node parseFieldType(JsDocToken token) { Node fieldName = parseFieldName(token); if (fieldName == null) { return null; } skipEOLs(); if (!match(JsDocToken.COLON)) { return fieldName; } // Move to the colon. next(); // Move to the token after the colon and parse // the type expression. skipEOLs(); Node typeExpression = parseTypeExpression(next()); if (typeExpression == null) { return null; } Node fieldType = newNode(Token.COLON); fieldType.addChildToBack(fieldName); fieldType.addChildToBack(typeExpression); return fieldType; }
/** * TopLevelTypeExpression := TypeExpression * | TypeUnionList * * We made this rule up, for the sake of backwards compatibility. */ private Node parseTopLevelTypeExpression(JsDocToken token) { Node typeExpr = parseTypeExpression(token); if (typeExpr != null) { // top-level unions are allowed if (match(JsDocToken.PIPE)) { next(); skipEOLs(); token = next(); return parseUnionTypeWithAlternate(token, typeExpr); } } return typeExpr; }
/** * TopLevelTypeExpression := TypeExpression * | TypeUnionList * * We made this rule up, for the sake of backwards compatibility. */ private Node parseTopLevelTypeExpression(JsDocToken token) { Node typeExpr = parseTypeExpression(token); if (typeExpr != null) { // top-level unions are allowed if (match(JsDocToken.PIPE)) { next(); skipEOLs(); token = next(); return parseUnionTypeWithAlternate(token, typeExpr); } } return typeExpr; }
/** * Parse a TypeName: * * <pre>{@code * TypeName := NameExpression | NameExpression TypeApplication * TypeApplication := '.'? '<' TypeExpressionList '>' * }</pre> */ private Node parseTypeName(JsDocToken token) { Node typeNameNode = parseNameExpression(token); if (match(JsDocToken.LEFT_ANGLE)) { next(); skipEOLs(); Node memberType = parseTypeExpressionList(typeNameNode.getString(), next()); if (memberType != null) { typeNameNode.addChildToFront(memberType); skipEOLs(); if (!match(JsDocToken.RIGHT_ANGLE)) { return reportTypeSyntaxWarning("msg.jsdoc.missing.gt"); } next(); } } return typeNameNode; }
/** * Important comments begin with /*! They are treated as license blocks, but no further JSDoc * parsing is performed */ void parseImportantComment() { state = State.SEARCHING_ANNOTATION; skipEOLs(); JsDocToken token = next(); ExtractionInfo info = extractMultilineComment(token, WhitespaceOption.PRESERVE, false, true); // An extra space is added by the @license annotation // so we need to add one here so they will be identical String license = " " + info.string; if (fileLevelJsDocBuilder != null) { fileLevelJsDocBuilder.addLicense(license); } else if (jsdocBuilder.shouldParseDocumentation()) { jsdocBuilder.recordBlockDescription(license); } else { jsdocBuilder.recordBlockDescription(""); } }
/** * RecordType := '{' FieldTypeList '}' */ private Node parseRecordType(JsDocToken token) { Node recordType = newNode(Token.LC); Node fieldTypeList = parseFieldTypeList(token); if (fieldTypeList == null) { return reportGenericTypeSyntaxWarning(); } skipEOLs(); if (!match(JsDocToken.RIGHT_CURLY)) { return reportTypeSyntaxWarning("msg.jsdoc.missing.rc"); } next(); recordType.addChildToBack(fieldTypeList); return recordType; }
/** * RecordType := '{' FieldTypeList '}' */ private Node parseRecordType(JsDocToken token) { Node recordType = newNode(Token.LC); Node fieldTypeList = parseFieldTypeList(token); if (fieldTypeList == null) { return reportGenericTypeSyntaxWarning(); } skipEOLs(); if (!match(JsDocToken.RIGHT_CURLY)) { return reportTypeSyntaxWarning("msg.jsdoc.missing.rc"); } next(); recordType.addChildToBack(fieldTypeList); return recordType; }
/** * TypeExpressionList := TopLevelTypeExpression * | TopLevelTypeExpression ',' TypeExpressionList */ private Node parseTypeExpressionList(JsDocToken token) { Node typeExpr = parseTopLevelTypeExpression(token); if (typeExpr == null) { return null; } Node typeList = IR.block(); typeList.addChildToBack(typeExpr); while (match(JsDocToken.COMMA)) { next(); skipEOLs(); typeExpr = parseTopLevelTypeExpression(next()); if (typeExpr == null) { return null; } typeList.addChildToBack(typeExpr); } return typeList; }
/** * Parse a description as a {@code @type}. */ public JSDocInfo parseInlineTypeDoc() { skipEOLs(); JsDocToken token = next(); int lineno = stream.getLineno(); int startCharno = stream.getCharno(); Node typeAst = parseParamTypeExpression(token); recordTypeNode(lineno, startCharno, typeAst, token == JsDocToken.LEFT_CURLY); JSTypeExpression expr = createJSTypeExpression(typeAst); if (expr != null) { jsdocBuilder.recordType(expr); jsdocBuilder.recordInlineType(); return retrieveAndResetParsedJSDocInfo(); } return null; }
/** * Parse a description as a {@code @type}. */ public JSDocInfo parseInlineTypeDoc() { skipEOLs(); JsDocToken token = next(); int lineno = stream.getLineno(); int startCharno = stream.getCharno(); Node typeAst = parseParamTypeExpression(token); recordTypeNode(lineno, startCharno, typeAst, token == JsDocToken.LEFT_CURLY); JSTypeExpression expr = createJSTypeExpression(typeAst); if (expr != null) { jsdocBuilder.recordType(expr); jsdocBuilder.recordInlineType(); return retrieveAndResetParsedJSDocInfo(); } return null; }