@@ -540,18 +540,44 @@ func readDigits(source: Source, start: Int, firstCode: UInt8) throws -> Int {
540540}
541541
542542/**
543- * Reads a string token from the source file.
543+ * Reads a `. string` token from the source file.
544544 *
545545 * "([^"\\\u000A\u000D]|(\\(u[0-9a-fA-F]{4}|["\\/bfnrt])))*"
546+ *
547+ * augmented to support blockstrings """ """ and return `.blockString` token if found.
546548 */
547549func readString( source: Source , start: Int , line: Int , col: Int , prev: Token ) throws -> Token {
550+ let token = try readRawString ( source: source, start: start, line: line, col: col, prev: prev)
551+
552+ if token. kind == . blockString,
553+ let rawString = token. value {
554+ let valueString = blockStringValue ( rawValue: rawString)
555+ return Token ( kind: token. kind,
556+ start: token. start,
557+ end: token. end,
558+ line: token. line,
559+ column: token. column,
560+ value: valueString,
561+ prev: token. prev,
562+ next: token. next)
563+ }
564+ return token
565+ }
566+
567+ /** Reads a raw string token from the source.
568+ *
569+ * Doesn't do any clean up of leading indentations or trailing whitespace for blockstring lines;
570+ * so if `token.kind` == `.blockString`, call `blockStringValue` with `token.value` for that.
571+ *
572+ * returns: Token of kind `.string` or `.blockString`
573+ */
574+ func readRawString( source: Source , start: Int , line: Int , col: Int , prev: Token ) throws -> Token {
548575 let body = source. body
549576 var positionIndex = body. utf8. index ( body. utf8. startIndex, offsetBy: start + 1 )
550577 var chunkStartIndex = positionIndex
551578 var currentCode : UInt8 ? = 0
552579 var value = " "
553580 var blockString = false
554- var chunkEndTrim = 0
555581
556582 // if we have minimum 5 more quotes worth of characters left after eating the first quote, check for block quote
557583 // body.utf8.index(positionIndex, offsetBy: 5) < body.utf8.endIndex
@@ -593,12 +619,7 @@ func readString(source: Source, start: Int, line: Int, col: Int, prev: Token) th
593619 codeNext == 34 ,
594620 let codeNextNext = body. charCode ( at: body. utf8. index ( after: body. utf8. index ( after: positionIndex) ) ) ,
595621 codeNextNext == 34 {
596- // if closing """ is on a line by itself then we set chunkEndTrim to 1 to trim the last return before it
597- if let code = body. charCode ( at: body. utf8. index ( before: positionIndex) ) ,
598- ( code == 0x000A || code == 0x000D ) {
599- chunkEndTrim = 1 // flag the need to trim the last return
600- }
601- positionIndex = body. utf8. index ( after: body. utf8. index ( after: positionIndex) ) // so we clean up on exit
622+ positionIndex = body. utf8. index ( after: body. utf8. index ( after: positionIndex) ) // so we clean up quotes on exit
602623 break
603624 }
604625
@@ -676,22 +697,26 @@ func readString(source: Source, start: Int, line: Int, col: Int, prev: Token) th
676697 )
677698 }
678699
679- let valueRangeEnd = body. utf8. index ( positionIndex, offsetBy: ( blockString ? - 2 - chunkEndTrim : 0 ) )
680- value += String ( body. utf8 [ chunkStartIndex ..< valueRangeEnd] ) !
700+ if blockString {
701+ let valueRangeEnd = body. utf8. index ( positionIndex, offsetBy: - 2 )
702+ if chunkStartIndex < valueRangeEnd { // empty string?
703+ value += String ( body. utf8 [ chunkStartIndex ..< valueRangeEnd] ) !
704+ }
705+ } else {
706+ value += String ( body. utf8 [ chunkStartIndex ..< positionIndex] ) !
707+ }
681708
682- return Token (
683- kind: . string,
684- start: start,
685- end: body. offset ( of: positionIndex) + 1 ,
686- line: line,
687- column: col,
688- value: value,
689- prev: prev
690- )
709+ return Token ( kind: blockString ? . blockString : . string,
710+ start: start,
711+ end: body. offset ( of: positionIndex) + 1 ,
712+ line: line,
713+ column: col,
714+ value: value,
715+ prev: prev)
691716}
692717
693718/**
694- * BlockStringValue (rawValue: String)
719+ * blockStringValue (rawValue: String)
695720 *
696721 * Transcription of the algorithm specified in the [spec](http://spec.graphql.org/draft/#BlockStringValue())
697722 *
@@ -723,8 +748,8 @@ func readString(source: Source, start: Int, line: Int, col: Int, prev: Token) th
723748 */
724749
725750func blockStringValue( rawValue: String ) -> String {
726- assert ( false , " implement this! " )
727- return " "
751+ print ( " \n \n **** blockStringValue Not Yet Implemented **** \n \n " )
752+ return rawValue
728753}
729754
730755/**
0 commit comments