module ts { var nodeConstructors = new Array < new ( ) => Node > ( SyntaxKind . Count ) ; export function getNodeConstructor ( kind ) { return nodeConstructors [ kind ] || ( nodeConstructors [ kind ] = objectAllocator . getNodeConstructor ( kind ) ) ; } function createRootNode ( kind , pos , end , flags ) { var node = new ( getNodeConstructor ( kind ) ) ( ) ; node . pos = pos ; node . end = end ; node . flags = flags ; return node ; } interface ReferenceComments { referencedFiles : FileReference [ ] ; amdDependencies : string [ ] ; amdModuleName : string ; } export function forEachChild < T > ( node , cbNode , cbNodes ? ) { function child ( node ) { if ( node ) { return cbNode ( node ) ; } } function children ( nodes ) { if ( nodes ) { if ( cbNodes ) { return cbNodes ( nodes ) ; } for ( var i = 0 , len = nodes . length ; i < len ; i ++ ) { var result = cbNode ( nodes [ i ] ) ; if ( result ) { return result ; } } return undefined ; } } if ( ! node ) { return ; } switch ( node . kind ) { case SyntaxKind . QualifiedName : return child ( ( < QualifiedName > node ) . left ) || child ( ( < QualifiedName > node ) . right ) ; case SyntaxKind . TypeParameter : return child ( ( < TypeParameterDeclaration > node ) . name ) || child ( ( < TypeParameterDeclaration > node ) . constraint ) ; case SyntaxKind . Parameter : return children ( node . modifiers ) || child ( ( < ParameterDeclaration > node ) . dotDotDotToken ) || child ( ( < ParameterDeclaration > node ) . name ) || child ( ( < ParameterDeclaration > node ) . questionToken ) || child ( ( < ParameterDeclaration > node ) . type ) || child ( ( < ParameterDeclaration > node ) . initializer ) ; case SyntaxKind . Property : case SyntaxKind . PropertyAssignment : case SyntaxKind . ShorthandPropertyAssignment : return children ( node . modifiers ) || child ( ( < PropertyDeclaration > node ) . name ) || child ( ( < PropertyDeclaration > node ) . questionToken ) || child ( ( < PropertyDeclaration > node ) . type ) || child ( ( < PropertyDeclaration > node ) . initializer ) ; case SyntaxKind . FunctionType : case SyntaxKind . ConstructorType : case SyntaxKind . CallSignature : case SyntaxKind . ConstructSignature : case SyntaxKind . IndexSignature : return children ( node . modifiers ) || children ( ( < SignatureDeclaration > node ) . typeParameters ) || children ( ( < SignatureDeclaration > node ) . parameters ) || child ( ( < SignatureDeclaration > node ) . type ) ; case SyntaxKind . Method : case SyntaxKind . Constructor : case SyntaxKind . GetAccessor : case SyntaxKind . SetAccessor : case SyntaxKind . FunctionExpression : case SyntaxKind . FunctionDeclaration : case SyntaxKind . ArrowFunction : return children ( node . modifiers ) || child ( ( < FunctionLikeDeclaration > node ) . name ) || child ( ( < FunctionLikeDeclaration > node ) . questionToken ) || children ( ( < FunctionLikeDeclaration > node ) . typeParameters ) || children ( ( < FunctionLikeDeclaration > node ) . parameters ) || child ( ( < FunctionLikeDeclaration > node ) . type ) || child ( ( < FunctionLikeDeclaration > node ) . body ) ; case SyntaxKind . TypeReference : return child ( ( < TypeReferenceNode > node ) . typeName ) || children ( ( < TypeReferenceNode > node ) . typeArguments ) ; case SyntaxKind . TypeQuery : return child ( ( < TypeQueryNode > node ) . exprName ) ; case SyntaxKind . TypeLiteral : return children ( ( < TypeLiteralNode > node ) . members ) ; case SyntaxKind . ArrayType : return child ( ( < ArrayTypeNode > node ) . elementType ) ; case SyntaxKind . TupleType : return children ( ( < TupleTypeNode > node ) . elementTypes ) ; case SyntaxKind . UnionType : return children ( ( < UnionTypeNode > node ) . types ) ; case SyntaxKind . ParenthesizedType : return child ( ( < ParenthesizedTypeNode > node ) . type ) ; case SyntaxKind . ArrayLiteralExpression : return children ( ( < ArrayLiteralExpression > node ) . elements ) ; case SyntaxKind . ObjectLiteralExpression : return children ( ( < ObjectLiteralExpression > node ) . properties ) ; case SyntaxKind . PropertyAccessExpression : return child ( ( < PropertyAccessExpression > node ) . expression ) || child ( ( < PropertyAccessExpression > node ) . name ) ; case SyntaxKind . ElementAccessExpression : return child ( ( < ElementAccessExpression > node ) . expression ) || child ( ( < ElementAccessExpression > node ) . argumentExpression ) ; case SyntaxKind . CallExpression : case SyntaxKind . NewExpression : return child ( ( < CallExpression > node ) . expression ) || children ( ( < CallExpression > node ) . typeArguments ) || children ( ( < CallExpression > node ) . arguments ) ; case SyntaxKind . TaggedTemplateExpression : return child ( ( < TaggedTemplateExpression > node ) . tag ) || child ( ( < TaggedTemplateExpression > node ) . template ) ; case SyntaxKind . TypeAssertionExpression : return child ( ( < TypeAssertion > node ) . type ) || child ( ( < TypeAssertion > node ) . expression ) ; case SyntaxKind . ParenthesizedExpression : return child ( ( < ParenthesizedExpression > node ) . expression ) ; case SyntaxKind . DeleteExpression : return child ( ( < DeleteExpression > node ) . expression ) ; case SyntaxKind . TypeOfExpression : return child ( ( < TypeOfExpression > node ) . expression ) ; case SyntaxKind . VoidExpression : return child ( ( < VoidExpression > node ) . expression ) ; case SyntaxKind . PrefixUnaryExpression : return child ( ( < PrefixUnaryExpression > node ) . operand ) ; case SyntaxKind . PostfixUnaryExpression : return child ( ( < PostfixUnaryExpression > node ) . operand ) ; case SyntaxKind . BinaryExpression : return child ( ( < BinaryExpression > node ) . left ) || child ( ( < BinaryExpression > node ) . right ) ; case SyntaxKind . ConditionalExpression : return child ( ( < ConditionalExpression > node ) . condition ) || child ( ( < ConditionalExpression > node ) . whenTrue ) || child ( ( < ConditionalExpression > node ) . whenFalse ) ; case SyntaxKind . Block : case SyntaxKind . TryBlock : case SyntaxKind . FinallyBlock : case SyntaxKind . ModuleBlock : return children ( ( < Block > node ) . statements ) ; case SyntaxKind . SourceFile : return children ( ( < SourceFile > node ) . statements ) || child ( ( < SourceFile > node ) . endOfFileToken ) ; case SyntaxKind . VariableStatement : return children ( node . modifiers ) || children ( ( < VariableStatement > node ) . declarations ) ; case SyntaxKind . ExpressionStatement : return child ( ( < ExpressionStatement > node ) . expression ) ; case SyntaxKind . IfStatement : return child ( ( < IfStatement > node ) . expression ) || child ( ( < IfStatement > node ) . thenStatement ) || child ( ( < IfStatement > node ) . elseStatement ) ; case SyntaxKind . DoStatement : return child ( ( < DoStatement > node ) . statement ) || child ( ( < DoStatement > node ) . expression ) ; case SyntaxKind . WhileStatement : return child ( ( < WhileStatement > node ) . expression ) || child ( ( < WhileStatement > node ) . statement ) ; case SyntaxKind . ForStatement : return children ( ( < ForStatement > node ) . declarations ) || child ( ( < ForStatement > node ) . initializer ) || child ( ( < ForStatement > node ) . condition ) || child ( ( < ForStatement > node ) . iterator ) || child ( ( < ForStatement > node ) . statement ) ; case SyntaxKind . ForInStatement : return children ( ( < ForInStatement > node ) . declarations ) || child ( ( < ForInStatement > node ) . variable ) || child ( ( < ForInStatement > node ) . expression ) || child ( ( < ForInStatement > node ) . statement ) ; case SyntaxKind . ContinueStatement : case SyntaxKind . BreakStatement : return child ( ( < BreakOrContinueStatement > node ) . label ) ; case SyntaxKind . ReturnStatement : return child ( ( < ReturnStatement > node ) . expression ) ; case SyntaxKind . WithStatement : return child ( ( < WithStatement > node ) . expression ) || child ( ( < WithStatement > node ) . statement ) ; case SyntaxKind . SwitchStatement : return child ( ( < SwitchStatement > node ) . expression ) || children ( ( < SwitchStatement > node ) . clauses ) ; case SyntaxKind . CaseClause : return child ( ( < CaseClause > node ) . expression ) || children ( ( < CaseClause > node ) . statements ) ; case SyntaxKind . DefaultClause : return children ( ( < DefaultClause > node ) . statements ) ; case SyntaxKind . LabeledStatement : return child ( ( < LabeledStatement > node ) . label ) || child ( ( < LabeledStatement > node ) . statement ) ; case SyntaxKind . ThrowStatement : return child ( ( < ThrowStatement > node ) . expression ) ; case SyntaxKind . TryStatement : return child ( ( < TryStatement > node ) . tryBlock ) || child ( ( < TryStatement > node ) . catchClause ) || child ( ( < TryStatement > node ) . finallyBlock ) ; case SyntaxKind . CatchClause : return child ( ( < CatchClause > node ) . name ) || child ( ( < CatchClause > node ) . type ) || child ( ( < CatchClause > node ) . block ) ; case SyntaxKind . VariableDeclaration : return children ( node . modifiers ) || child ( ( < VariableDeclaration > node ) . name ) || child ( ( < VariableDeclaration > node ) . type ) || child ( ( < VariableDeclaration > node ) . initializer ) ; case SyntaxKind . ClassDeclaration : return children ( node . modifiers ) || child ( ( < ClassDeclaration > node ) . name ) || children ( ( < ClassDeclaration > node ) . typeParameters ) || children ( ( < ClassDeclaration > node ) . heritageClauses ) || children ( ( < ClassDeclaration > node ) . members ) ; case SyntaxKind . InterfaceDeclaration : return children ( node . modifiers ) || child ( ( < InterfaceDeclaration > node ) . name ) || children ( ( < InterfaceDeclaration > node ) . typeParameters ) || children ( ( < ClassDeclaration > node ) . heritageClauses ) || children ( ( < InterfaceDeclaration > node ) . members ) ; case SyntaxKind . TypeAliasDeclaration : return children ( node . modifiers ) || child ( ( < TypeAliasDeclaration > node ) . name ) || child ( ( < TypeAliasDeclaration > node ) . type ) ; case SyntaxKind . EnumDeclaration : return children ( node . modifiers ) || child ( ( < EnumDeclaration > node ) . name ) || children ( ( < EnumDeclaration > node ) . members ) ; case SyntaxKind . EnumMember : return child ( ( < EnumMember > node ) . name ) || child ( ( < EnumMember > node ) . initializer ) ; case SyntaxKind . ModuleDeclaration : return children ( node . modifiers ) || child ( ( < ModuleDeclaration > node ) . name ) || child ( ( < ModuleDeclaration > node ) . body ) ; case SyntaxKind . ImportDeclaration : return children ( node . modifiers ) || child ( ( < ImportDeclaration > node ) . name ) || child ( ( < ImportDeclaration > node ) . moduleReference ) ; case SyntaxKind . ExportAssignment : return children ( node . modifiers ) || child ( ( < ExportAssignment > node ) . exportName ) ; case SyntaxKind . TemplateExpression : return child ( ( < TemplateExpression > node ) . head ) || children ( ( < TemplateExpression > node ) . templateSpans ) ; case SyntaxKind . TemplateSpan : return child ( ( < TemplateSpan > node ) . expression ) || child ( ( < TemplateSpan > node ) . literal ) ; case SyntaxKind . ComputedPropertyName : return child ( ( < ComputedPropertyName > node ) . expression ) ; case SyntaxKind . HeritageClause : return children ( ( < HeritageClause > node ) . types ) ; case SyntaxKind . ExternalModuleReference : return child ( ( < ExternalModuleReference > node ) . expression ) ; } } export function createCompilerHost ( options ) { var currentDirectory ; var existingDirectories = { } ; function getCanonicalFileName ( fileName ) { return sys . useCaseSensitiveFileNames ? fileName : fileName . toLowerCase ( ) ; } var unsupportedFileEncodingErrorCode = - 2147024809 ; function getSourceFile ( filename , languageVersion , onError ? ) { try { var text = sys . readFile ( filename , options . charset ) ; } catch ( e ) { if ( onError ) { onError ( e . number === unsupportedFileEncodingErrorCode ? createCompilerDiagnostic ( Diagnostics . Unsupported_file_encoding ) . messageText : e . message ) ; } text = "" ; } return text !== undefined ? createSourceFile ( filename , text , languageVersion , "0" ) : undefined ; } function writeFile ( fileName , data , writeByteOrderMark , onError ? ) { function directoryExists ( directoryPath ) { if ( hasProperty ( existingDirectories , directoryPath ) ) { return true ; } if ( sys . directoryExists ( directoryPath ) ) { existingDirectories [ directoryPath ] = true ; return true ; } return false ; } function ensureDirectoriesExist ( directoryPath ) { if ( directoryPath . length > getRootLength ( directoryPath ) && ! directoryExists ( directoryPath ) ) { var parentDirectory = getDirectoryPath ( directoryPath ) ; ensureDirectoriesExist ( parentDirectory ) ; sys . createDirectory ( directoryPath ) ; } } try { ensureDirectoriesExist ( getDirectoryPath ( normalizePath ( fileName ) ) ) ; sys . writeFile ( fileName , data , writeByteOrderMark ) ; } catch ( e ) { if ( onError ) { onError ( e . message ) ; } } } return { getSourceFile , getDefaultLibFilename : options => combinePaths ( getDirectoryPath ( normalizePath ( sys . getExecutingFilePath ( ) ) ) , options . target === ScriptTarget . ES6 ? "lib.es6.d.ts" : "lib.d.ts" ) , writeFile , getCurrentDirectory : ( ) => currentDirectory || ( currentDirectory = sys . getCurrentDirectory ( ) ) , useCaseSensitiveFileNames : ( ) => sys . useCaseSensitiveFileNames , getCanonicalFileName , getNewLine : ( ) => sys . newLine } ; } const enum ParsingContext { SourceElements , ModuleElements , BlockStatements , SwitchClauses , SwitchClauseStatements , TypeMembers , ClassMembers , EnumMembers , TypeReferences , VariableDeclarations , ArgumentExpressions , ObjectLiteralMembers , ArrayLiteralMembers , Parameters , TypeParameters , TypeArguments , TupleElementTypes , HeritageClauses , Count } const enum Tristate { False , True , Unknown } function parsingContextErrors ( context ) { switch ( context ) { case ParsingContext . SourceElements : return Diagnostics . Declaration_or_statement_expected ; case ParsingContext . ModuleElements : return Diagnostics . Declaration_or_statement_expected ; case ParsingContext . BlockStatements : return Diagnostics . Statement_expected ; case ParsingContext . SwitchClauses : return Diagnostics . case_or_default_expected ; case ParsingContext . SwitchClauseStatements : return Diagnostics . Statement_expected ; case ParsingContext . TypeMembers : return Diagnostics . Property_or_signature_expected ; case ParsingContext . ClassMembers : return Diagnostics . Unexpected_token_A_constructor_method_accessor_or_property_was_expected ; case ParsingContext . EnumMembers : return Diagnostics . Enum_member_expected ; case ParsingContext . TypeReferences : return Diagnostics . Type_reference_expected ; case ParsingContext . VariableDeclarations : return Diagnostics . Variable_declaration_expected ; case ParsingContext . ArgumentExpressions : return Diagnostics . Argument_expression_expected ; case ParsingContext . ObjectLiteralMembers : return Diagnostics . Property_assignment_expected ; case ParsingContext . ArrayLiteralMembers : return Diagnostics . Expression_or_comma_expected ; case ParsingContext . Parameters : return Diagnostics . Parameter_declaration_expected ; case ParsingContext . TypeParameters : return Diagnostics . Type_parameter_declaration_expected ; case ParsingContext . TypeArguments : return Diagnostics . Type_argument_expected ; case ParsingContext . TupleElementTypes : return Diagnostics . Type_expected ; case ParsingContext . HeritageClauses : return Diagnostics . Unexpected_token_expected ; } } ; function modifierToFlag ( token ) { switch ( token ) { case SyntaxKind . StaticKeyword : return NodeFlags . Static ; case SyntaxKind . PublicKeyword : return NodeFlags . Public ; case SyntaxKind . ProtectedKeyword : return NodeFlags . Protected ; case SyntaxKind . PrivateKeyword : return NodeFlags . Private ; case SyntaxKind . ExportKeyword : return NodeFlags . Export ; case SyntaxKind . DeclareKeyword : return NodeFlags . Ambient ; case SyntaxKind . ConstKeyword : return NodeFlags . Const ; } return 0 ; } function isEvalOrArgumentsIdentifier ( node ) { return node . kind === SyntaxKind . Identifier && ( ( < Identifier > node ) . text === "eval" || ( < Identifier > node ) . text === "arguments" ) ; } function isUseStrictPrologueDirective ( sourceFile , node ) { Debug . assert ( isPrologueDirective ( node ) ) ; var nodeText = getSourceTextOfNodeFromSourceFile ( sourceFile , ( < ExpressionStatement > node ) . expression ) ; return nodeText === '"use strict"' || nodeText === "'use strict'" ; } export function createSourceFile ( filename , sourceText , languageVersion , version , isOpen = false ) { var token ; var parsingContext ; var identifiers = { } ; var identifierCount = 0 ; var nodeCount = 0 ; var lineStarts ; var contextFlags = 0 ; var parseErrorBeforeNextFinishedNode = false ; function setContextFlag ( val , flag ) { if ( val ) { contextFlags |= flag ; } else { contextFlags &= ~ flag ; } } function setStrictModeContext ( val ) { setContextFlag ( val , ParserContextFlags . StrictMode ) ; } function setDisallowInContext ( val ) { setContextFlag ( val , ParserContextFlags . DisallowIn ) ; } function setYieldContext ( val ) { setContextFlag ( val , ParserContextFlags . Yield ) ; } function setGeneratorParameterContext ( val ) { setContextFlag ( val , ParserContextFlags . GeneratorParameter ) ; } function allowInAnd < T > ( func ) { if ( contextFlags & ParserContextFlags . DisallowIn ) { setDisallowInContext ( false ) ; var result = func ( ) ; setDisallowInContext ( true ) ; return result ; } return func ( ) ; } function disallowInAnd < T > ( func ) { if ( contextFlags & ParserContextFlags . DisallowIn ) { return func ( ) ; } setDisallowInContext ( true ) ; var result = func ( ) ; setDisallowInContext ( false ) ; return result ; } function doInYieldContext < T > ( func ) { if ( contextFlags & ParserContextFlags . Yield ) { return func ( ) ; } setYieldContext ( true ) ; var result = func ( ) ; setYieldContext ( false ) ; return result ; } function doOutsideOfYieldContext < T > ( func ) { if ( contextFlags & ParserContextFlags . Yield ) { setYieldContext ( false ) ; var result = func ( ) ; setYieldContext ( true ) ; return result ; } return func ( ) ; } function inYieldContext ( ) { return ( contextFlags & ParserContextFlags . Yield ) !== 0 ; } function inStrictModeContext ( ) { return ( contextFlags & ParserContextFlags . StrictMode ) !== 0 ; } function inGeneratorParameterContext ( ) { return ( contextFlags & ParserContextFlags . GeneratorParameter ) !== 0 ; } function inDisallowInContext ( ) { return ( contextFlags & ParserContextFlags . DisallowIn ) !== 0 ; } function getLineStarts ( ) { return lineStarts || ( lineStarts = computeLineStarts ( sourceText ) ) ; } function getLineAndCharacterFromSourcePosition ( position ) { return getLineAndCharacterOfPosition ( getLineStarts ( ) , position ) ; } function getPositionFromSourceLineAndCharacter ( line , character ) { return getPositionFromLineAndCharacter ( getLineStarts ( ) , line , character ) ; } function parseErrorAtCurrentToken ( message , arg0 ? ) { var start = scanner . getTokenPos ( ) ; var length = scanner . getTextPos ( ) - start ; parseErrorAtPosition ( start , length , message , arg0 ) ; } function parseErrorAtPosition ( start , length , message , arg0 ? ) { var lastError = lastOrUndefined ( sourceFile . parseDiagnostics ) ; if ( ! lastError || start !== lastError . start ) { sourceFile . parseDiagnostics . push ( createFileDiagnostic ( sourceFile , start , length , message , arg0 ) ) ; } parseErrorBeforeNextFinishedNode = true ; } function scanError ( message ) { var pos = scanner . getTextPos ( ) ; parseErrorAtPosition ( pos , 0 , message ) ; } function getNodePos ( ) { return scanner . getStartPos ( ) ; } function getNodeEnd ( ) { return scanner . getStartPos ( ) ; } function nextToken ( ) { return token = scanner . scan ( ) ; } function getTokenPos ( pos ) { return skipTrivia ( sourceText , pos ) ; } function reScanGreaterToken ( ) { return token = scanner . reScanGreaterToken ( ) ; } function reScanSlashToken ( ) { return token = scanner . reScanSlashToken ( ) ; } function reScanTemplateToken ( ) { return token = scanner . reScanTemplateToken ( ) ; } function speculationHelper < T > ( callback , isLookAhead ) { var saveToken = token ; var saveParseDiagnosticsLength = sourceFile . parseDiagnostics . length ; var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode ; var saveContextFlags = contextFlags ; var result = isLookAhead ? scanner . lookAhead ( callback ) : scanner . tryScan ( callback ) ; Debug . assert ( saveContextFlags === contextFlags ) ; if ( ! result || isLookAhead ) { token = saveToken ; sourceFile . parseDiagnostics . length = saveParseDiagnosticsLength ; parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode ; } return result ; } function lookAhead < T > ( callback ) { return speculationHelper ( callback , true ) ; } function tryParse < T > ( callback ) { return speculationHelper ( callback , false ) ; } function isIdentifier ( ) { if ( token === SyntaxKind . Identifier ) { return true ; } if ( token === SyntaxKind . YieldKeyword && inYieldContext ( ) ) { return false ; } return inStrictModeContext ( ) ? token > SyntaxKind . LastFutureReservedWord : token > SyntaxKind . LastReservedWord ; } function parseExpected ( kind , diagnosticMessage ? , arg0 ? ) { if ( token === kind ) { nextToken ( ) ; return true ; } if ( diagnosticMessage ) { parseErrorAtCurrentToken ( diagnosticMessage , arg0 ) ; } else { parseErrorAtCurrentToken ( Diagnostics . _0_expected , tokenToString ( kind ) ) ; } return false ; } function parseOptional ( t ) { if ( token === t ) { nextToken ( ) ; return true ; } return false ; } function parseOptionalToken ( t ) { if ( token === t ) { var node = createNode ( t ) ; nextToken ( ) ; return finishNode ( node ) ; } return undefined ; } function canParseSemicolon ( ) { if ( token === SyntaxKind . SemicolonToken ) { return true ; } return token === SyntaxKind . CloseBraceToken || token === SyntaxKind . EndOfFileToken || scanner . hasPrecedingLineBreak ( ) ; } function parseSemicolon ( diagnosticMessage ? ) { if ( canParseSemicolon ( ) ) { if ( token === SyntaxKind . SemicolonToken ) { nextToken ( ) ; } return true ; } else { return parseExpected ( SyntaxKind . SemicolonToken , diagnosticMessage ) ; } } function createNode ( kind , pos ? ) { nodeCount ++ ; var node = new ( nodeConstructors [ kind ] || ( nodeConstructors [ kind ] = objectAllocator . getNodeConstructor ( kind ) ) ) ( ) ; if ( ! ( pos >= 0 ) ) { pos = scanner . getStartPos ( ) ; } node . pos = pos ; node . end = pos ; return node ; } function finishNode < T extends Node > ( node ) { node . end = scanner . getStartPos ( ) ; if ( contextFlags ) { node . parserContextFlags = contextFlags ; } if ( parseErrorBeforeNextFinishedNode ) { parseErrorBeforeNextFinishedNode = false ; node . parserContextFlags |= ParserContextFlags . ContainsError ; } return node ; } function createMissingNode ( kind , reportAtCurrentPosition , diagnosticMessage , arg0 ? ) { if ( reportAtCurrentPosition ) { parseErrorAtPosition ( scanner . getStartPos ( ) , 0 , diagnosticMessage , arg0 ) ; } else { parseErrorAtCurrentToken ( diagnosticMessage , arg0 ) ; } var result = createNode ( kind , scanner . getStartPos ( ) ) ; ( < Identifier > result ) . text = "" ; return finishNode ( result ) ; } function internIdentifier ( text ) { text = escapeIdentifier ( text ) ; return hasProperty ( identifiers , text ) ? identifiers [ text ] : ( identifiers [ text ] = text ) ; } function createIdentifier ( isIdentifier , diagnosticMessage ? ) { identifierCount ++ ; if ( isIdentifier ) { var node = < Identifier > createNode ( SyntaxKind . Identifier ) ; node . text = internIdentifier ( scanner . getTokenValue ( ) ) ; nextToken ( ) ; return finishNode ( node ) ; } return < Identifier > createMissingNode ( SyntaxKind . Identifier , false , diagnosticMessage || Diagnostics . Identifier_expected ) ; } function parseIdentifier ( diagnosticMessage ? ) { return createIdentifier ( isIdentifier ( ) , diagnosticMessage ) ; } function parseIdentifierName ( ) { return createIdentifier ( isIdentifierOrKeyword ( ) ) ; } function isLiteralPropertyName ( ) { return isIdentifierOrKeyword ( ) || token === SyntaxKind . StringLiteral || token === SyntaxKind . NumericLiteral ; } function parsePropertyName ( ) { if ( token === SyntaxKind . StringLiteral || token === SyntaxKind . NumericLiteral ) { return parseLiteralNode ( true ) ; } if ( token === SyntaxKind . OpenBracketToken ) { return parseComputedPropertyName ( ) ; } return parseIdentifierName ( ) ; } function parseComputedPropertyName ( ) { var node = < ComputedPropertyName > createNode ( SyntaxKind . ComputedPropertyName ) ; parseExpected ( SyntaxKind . OpenBracketToken ) ; var yieldContext = inYieldContext ( ) ; if ( inGeneratorParameterContext ( ) ) { setYieldContext ( false ) ; } node . expression = allowInAnd ( parseExpression ) ; if ( inGeneratorParameterContext ( ) ) { setYieldContext ( yieldContext ) ; } parseExpected ( SyntaxKind . CloseBracketToken ) ; return finishNode ( node ) ; } function parseContextualModifier ( t ) { return token === t && tryParse ( nextTokenCanFollowModifier ) ; } function nextTokenCanFollowModifier ( ) { nextToken ( ) ; return canFollowModifier ( ) ; } function parseAnyContextualModifier ( ) { return isModifier ( token ) && tryParse ( nextTokenCanFollowContextualModifier ) ; } function nextTokenCanFollowContextualModifier ( ) { if ( token === SyntaxKind . ConstKeyword ) { return nextToken ( ) === SyntaxKind . EnumKeyword ; } nextToken ( ) ; return canFollowModifier ( ) ; } function canFollowModifier ( ) { return token === SyntaxKind . OpenBracketToken || token === SyntaxKind . AsteriskToken || isLiteralPropertyName ( ) ; } function isListElement ( kind , inErrorRecovery ) { switch ( kind ) { case ParsingContext . SourceElements : case ParsingContext . ModuleElements : return isSourceElement ( inErrorRecovery ) ; case ParsingContext . BlockStatements : case ParsingContext . SwitchClauseStatements : return isStatement ( inErrorRecovery ) ; case ParsingContext . SwitchClauses : return token === SyntaxKind . CaseKeyword || token === SyntaxKind . DefaultKeyword ; case ParsingContext . TypeMembers : return isStartOfTypeMember ( ) ; case ParsingContext . ClassMembers : return lookAhead ( isClassMemberStart ) ; case ParsingContext . EnumMembers : return token === SyntaxKind . OpenBracketToken || isLiteralPropertyName ( ) ; case ParsingContext . ObjectLiteralMembers : return token === SyntaxKind . OpenBracketToken || token === SyntaxKind . AsteriskToken || isLiteralPropertyName ( ) ; case ParsingContext . TypeReferences : return isIdentifier ( ) && ! isNotHeritageClauseTypeName ( ) ; case ParsingContext . VariableDeclarations : case ParsingContext . TypeParameters : return isIdentifier ( ) ; case ParsingContext . ArgumentExpressions : return token === SyntaxKind . CommaToken || isStartOfExpression ( ) ; case ParsingContext . ArrayLiteralMembers : return token === SyntaxKind . CommaToken || isStartOfExpression ( ) ; case ParsingContext . Parameters : return isStartOfParameter ( ) ; case ParsingContext . TypeArguments : case ParsingContext . TupleElementTypes : return token === SyntaxKind . CommaToken || isStartOfType ( ) ; case ParsingContext . HeritageClauses : return isHeritageClause ( ) ; } Debug . fail ( "Non-exhaustive case in 'isListElement'." ) ; } function nextTokenIsIdentifier ( ) { nextToken ( ) ; return isIdentifier ( ) ; } function isNotHeritageClauseTypeName ( ) { if ( token === SyntaxKind . ImplementsKeyword || token === SyntaxKind . ExtendsKeyword ) { return lookAhead ( nextTokenIsIdentifier ) ; } return false ; } function isListTerminator ( kind ) { if ( token === SyntaxKind . EndOfFileToken ) { return true ; } switch ( kind ) { case ParsingContext . ModuleElements : case ParsingContext . BlockStatements : case ParsingContext . SwitchClauses : case ParsingContext . TypeMembers : case ParsingContext . ClassMembers : case ParsingContext . EnumMembers : case ParsingContext . ObjectLiteralMembers : return token === SyntaxKind . CloseBraceToken ; case ParsingContext . SwitchClauseStatements : return token === SyntaxKind . CloseBraceToken || token === SyntaxKind . CaseKeyword || token === SyntaxKind . DefaultKeyword ; case ParsingContext . TypeReferences : return token === SyntaxKind . OpenBraceToken || token === SyntaxKind . ExtendsKeyword || token === SyntaxKind . ImplementsKeyword ; case ParsingContext . VariableDeclarations : return isVariableDeclaratorListTerminator ( ) ; case ParsingContext . TypeParameters : return token === SyntaxKind . GreaterThanToken || token === SyntaxKind . OpenParenToken || token === SyntaxKind . OpenBraceToken || token === SyntaxKind . ExtendsKeyword || token === SyntaxKind . ImplementsKeyword ; case ParsingContext . ArgumentExpressions : return token === SyntaxKind . CloseParenToken || token === SyntaxKind . SemicolonToken ; case ParsingContext . ArrayLiteralMembers : case ParsingContext . TupleElementTypes : return token === SyntaxKind . CloseBracketToken ; case ParsingContext . Parameters : return token === SyntaxKind . CloseParenToken || token === SyntaxKind . CloseBracketToken || token === SyntaxKind . OpenBraceToken ; case ParsingContext . TypeArguments : return token === SyntaxKind . GreaterThanToken || token === SyntaxKind . OpenParenToken ; case ParsingContext . HeritageClauses : return token === SyntaxKind . OpenBraceToken || token === SyntaxKind . CloseBraceToken ; } } function isVariableDeclaratorListTerminator ( ) { if ( canParseSemicolon ( ) ) { return true ; } if ( token === SyntaxKind . InKeyword ) { return true ; } if ( token === SyntaxKind . EqualsGreaterThanToken ) { return true ; } return false ; } function isInSomeParsingContext ( ) { for ( var kind = 0 ; kind < ParsingContext . Count ; kind ++ ) { if ( parsingContext & ( 1 << kind ) ) { if ( isListElement ( kind , true ) || isListTerminator ( kind ) ) { return true ; } } } return false ; } function parseList < T extends Node > ( kind , checkForStrictMode , parseElement ) { var saveParsingContext = parsingContext ; parsingContext |= 1 << kind ; var result = < NodeArray < T > > [ ] ; result . pos = getNodePos ( ) ; var savedStrictModeContext = inStrictModeContext ( ) ; while ( ! isListTerminator ( kind ) ) { if ( isListElement ( kind , false ) ) { var element = parseElement ( ) ; result . push ( element ) ; if ( checkForStrictMode && ! inStrictModeContext ( ) ) { if ( isPrologueDirective ( element ) ) { if ( isUseStrictPrologueDirective ( sourceFile , element ) ) { setStrictModeContext ( true ) ; checkForStrictMode = false ; } } else { checkForStrictMode = false ; } } continue ; } if ( abortParsingListOrMoveToNextToken ( kind ) ) { break ; } } setStrictModeContext ( savedStrictModeContext ) ; result . end = getNodeEnd ( ) ; parsingContext = saveParsingContext ; return result ; } function abortParsingListOrMoveToNextToken ( kind ) { parseErrorAtCurrentToken ( parsingContextErrors ( kind ) ) ; if ( isInSomeParsingContext ( ) ) { return true ; } nextToken ( ) ; return false ; } function parseDelimitedList < T extends Node > ( kind , parseElement ) { var saveParsingContext = parsingContext ; parsingContext |= 1 << kind ; var result = < NodeArray < T > > [ ] ; result . pos = getNodePos ( ) ; var commaStart = - 1 ; while ( true ) { if ( isListElement ( kind , false ) ) { result . push ( parseElement ( ) ) ; commaStart = scanner . getTokenPos ( ) ; if ( parseOptional ( SyntaxKind . CommaToken ) ) { continue ; } commaStart = - 1 ; if ( isListTerminator ( kind ) ) { break ; } parseExpected ( SyntaxKind . CommaToken ) ; continue ; } if ( isListTerminator ( kind ) ) { break ; } if ( abortParsingListOrMoveToNextToken ( kind ) ) { break ; } } if ( commaStart >= 0 ) { result . hasTrailingComma = true ; } result . end = getNodeEnd ( ) ; parsingContext = saveParsingContext ; return result ; } function createMissingList < T > ( ) { var pos = getNodePos ( ) ; var result = < NodeArray < T > > [ ] ; result . pos = pos ; result . end = pos ; return result ; } function parseBracketedList < T extends Node > ( kind , parseElement , open , close ) { if ( parseExpected ( open ) ) { var result = parseDelimitedList ( kind , parseElement ) ; parseExpected ( close ) ; return result ; } return createMissingList < T > ( ) ; } function parseEntityName ( allowReservedWords , diagnosticMessage ? ) { var entity = parseIdentifier ( diagnosticMessage ) ; while ( parseOptional ( SyntaxKind . DotToken ) ) { var node = < QualifiedName > createNode ( SyntaxKind . QualifiedName , entity . pos ) ; node . left = entity ; node . right = parseRightSideOfDot ( allowReservedWords ) ; entity = finishNode ( node ) ; } return entity ; } function parseRightSideOfDot ( allowIdentifierNames ) { if ( scanner . hasPrecedingLineBreak ( ) && scanner . isReservedWord ( ) ) { var matchesPattern = lookAhead ( nextTokenIsIdentifierOrKeywordOnSameLine ) ; if ( matchesPattern ) { return < Identifier > createMissingNode ( SyntaxKind . Identifier , true , Diagnostics . Identifier_expected ) ; } } return allowIdentifierNames ? parseIdentifierName ( ) : parseIdentifier ( ) ; } function parseTokenNode < T extends Node > ( ) { var node = < T > createNode ( token ) ; nextToken ( ) ; return finishNode ( node ) ; } function parseTemplateExpression ( ) { var template = < TemplateExpression > createNode ( SyntaxKind . TemplateExpression ) ; template . head = parseLiteralNode ( ) ; Debug . assert ( template . head . kind === SyntaxKind . TemplateHead , "Template head has wrong token kind" ) ; var templateSpans = < NodeArray < TemplateSpan > > [ ] ; templateSpans . pos = getNodePos ( ) ; do { templateSpans . push ( parseTemplateSpan ( ) ) ; } while ( templateSpans [ templateSpans . length - 1 ] . literal . kind === SyntaxKind . TemplateMiddle ) ; templateSpans . end = getNodeEnd ( ) ; template . templateSpans = templateSpans ; return finishNode ( template ) ; } function parseTemplateSpan ( ) { var span = < TemplateSpan > createNode ( SyntaxKind . TemplateSpan ) ; span . expression = allowInAnd ( parseExpression ) ; var literal ; if ( token === SyntaxKind . CloseBraceToken ) { reScanTemplateToken ( ) ; literal = parseLiteralNode ( ) ; } else { literal = < LiteralExpression > createMissingNode ( SyntaxKind . TemplateTail , false , Diagnostics . _0_expected , tokenToString ( SyntaxKind . CloseBraceToken ) ) ; } span . literal = literal ; return finishNode ( span ) ; } function parseLiteralNode ( internName ? ) { var node = < LiteralExpression > createNode ( token ) ; var text = scanner . getTokenValue ( ) ; node . text = internName ? internIdentifier ( text ) : text ; if ( scanner . isUnterminated ( ) ) { node . isUnterminated = true ; } var tokenPos = scanner . getTokenPos ( ) ; nextToken ( ) ; finishNode ( node ) ; if ( node . kind === SyntaxKind . NumericLiteral && sourceText . charCodeAt ( tokenPos ) === CharacterCodes . _0 && isOctalDigit ( sourceText . charCodeAt ( tokenPos + 1 ) ) ) { node . flags |= NodeFlags . OctalLiteral ; } return node ; } function parseTypeReference ( ) { var node = < TypeReferenceNode > createNode ( SyntaxKind . TypeReference ) ; node . typeName = parseEntityName ( false , Diagnostics . Type_expected ) ; if ( ! scanner . hasPrecedingLineBreak ( ) && token === SyntaxKind . LessThanToken ) { node . typeArguments = parseBracketedList ( ParsingContext . TypeArguments , parseType , SyntaxKind . LessThanToken , SyntaxKind . GreaterThanToken ) ; } return finishNode ( node ) ; } function parseTypeQuery ( ) { var node = < TypeQueryNode > createNode ( SyntaxKind . TypeQuery ) ; parseExpected ( SyntaxKind . TypeOfKeyword ) ; node . exprName = parseEntityName ( true ) ; return finishNode ( node ) ; } function parseTypeParameter ( ) { var node = < TypeParameterDeclaration > createNode ( SyntaxKind . TypeParameter ) ; node . name = parseIdentifier ( ) ; if ( parseOptional ( SyntaxKind . ExtendsKeyword ) ) { if ( isStartOfType ( ) || ! isStartOfExpression ( ) ) { node . constraint = parseType ( ) ; } else { node . expression = parseUnaryExpressionOrHigher ( ) ; } } return finishNode ( node ) ; } function parseTypeParameters ( ) { if ( token === SyntaxKind . LessThanToken ) { return parseBracketedList ( ParsingContext . TypeParameters , parseTypeParameter , SyntaxKind . LessThanToken , SyntaxKind . GreaterThanToken ) ; } } function parseParameterType ( ) { if ( parseOptional ( SyntaxKind . ColonToken ) ) { return token === SyntaxKind . StringLiteral ? < StringLiteralExpression > parseLiteralNode ( true ) : parseType ( ) ; } return undefined ; } function isStartOfParameter ( ) { return token === SyntaxKind . DotDotDotToken || isIdentifier ( ) || isModifier ( token ) ; } function setModifiers ( node , modifiers ) { if ( modifiers ) { node . flags |= modifiers . flags ; node . modifiers = modifiers ; } } function parseParameter ( ) { var node = < ParameterDeclaration > createNode ( SyntaxKind . Parameter ) ; setModifiers ( node , parseModifiers ( ) ) ; node . dotDotDotToken = parseOptionalToken ( SyntaxKind . DotDotDotToken ) ; node . name = inGeneratorParameterContext ( ) ? doInYieldContext ( parseIdentifier ) : parseIdentifier ( ) ; if ( getFullWidth ( node . name ) === 0 && node . flags === 0 && isModifier ( token ) ) { nextToken ( ) ; } node . questionToken = parseOptionalToken ( SyntaxKind . QuestionToken ) ; node . type = parseParameterType ( ) ; node . initializer = inGeneratorParameterContext ( ) ? doOutsideOfYieldContext ( parseParameterInitializer ) : parseParameterInitializer ( ) ; return finishNode ( node ) ; } function parseParameterInitializer ( ) { return parseInitializer ( true ) ; } function fillSignature ( returnToken , yieldAndGeneratorParameterContext , requireCompleteParameterList , signature ) { var returnTokenRequired = returnToken === SyntaxKind . EqualsGreaterThanToken ; signature . typeParameters = parseTypeParameters ( ) ; signature . parameters = parseParameterList ( yieldAndGeneratorParameterContext , requireCompleteParameterList ) ; if ( returnTokenRequired ) { parseExpected ( returnToken ) ; signature . type = parseType ( ) ; } else if ( parseOptional ( returnToken ) ) { signature . type = parseType ( ) ; } } function parseParameterList ( yieldAndGeneratorParameterContext , requireCompleteParameterList ) { if ( parseExpected ( SyntaxKind . OpenParenToken ) ) { var savedYieldContext = inYieldContext ( ) ; var savedGeneratorParameterContext = inGeneratorParameterContext ( ) ; setYieldContext ( yieldAndGeneratorParameterContext ) ; setGeneratorParameterContext ( yieldAndGeneratorParameterContext ) ; var result = parseDelimitedList ( ParsingContext . Parameters , parseParameter ) ; setYieldContext ( savedYieldContext ) ; setGeneratorParameterContext ( savedGeneratorParameterContext ) ; if ( ! parseExpected ( SyntaxKind . CloseParenToken ) && requireCompleteParameterList ) { return undefined ; } return result ; } return requireCompleteParameterList ? undefined : createMissingList < ParameterDeclaration > ( ) ; } function parseTypeMemberSemicolon ( ) { if ( parseSemicolon ( ) ) { return ; } parseOptional ( SyntaxKind . CommaToken ) ; } function parseSignatureMember ( kind ) { var node = < SignatureDeclaration > createNode ( kind ) ; if ( kind === SyntaxKind . ConstructSignature ) { parseExpected ( SyntaxKind . NewKeyword ) ; } fillSignature ( SyntaxKind . ColonToken , false , false , node ) ; parseTypeMemberSemicolon ( ) ; return finishNode ( node ) ; } function isIndexSignature ( ) { if ( token !== SyntaxKind . OpenBracketToken ) { return false ; } return lookAhead ( isUnambiguouslyIndexSignature ) ; } function isUnambiguouslyIndexSignature ( ) { nextToken ( ) ; if ( token === SyntaxKind . DotDotDotToken || token === SyntaxKind . CloseBracketToken ) { return true ; } if ( isModifier ( token ) ) { nextToken ( ) ; if ( isIdentifier ( ) ) { return true ; } } else if ( ! isIdentifier ( ) ) { return false ; } else { nextToken ( ) ; } if ( token === SyntaxKind . ColonToken || token === SyntaxKind . CommaToken ) { return true ; } if ( token !== SyntaxKind . QuestionToken ) { return false ; } nextToken ( ) ; return token === SyntaxKind . ColonToken || token === SyntaxKind . CommaToken || token === SyntaxKind . CloseBracketToken ; } function parseIndexSignatureDeclaration ( fullStart , modifiers ) { var node = < IndexSignatureDeclaration > createNode ( SyntaxKind . IndexSignature , fullStart ) ; setModifiers ( node , modifiers ) ; node . parameters = parseBracketedList ( ParsingContext . Parameters , parseParameter , SyntaxKind . OpenBracketToken , SyntaxKind . CloseBracketToken ) ; node . type = parseTypeAnnotation ( ) ; parseTypeMemberSemicolon ( ) ; return finishNode ( node ) ; } function parsePropertyOrMethodSignature ( ) { var fullStart = scanner . getStartPos ( ) ; var name = parsePropertyName ( ) ; var questionToken = parseOptionalToken ( SyntaxKind . QuestionToken ) ; if ( token === SyntaxKind . OpenParenToken || token === SyntaxKind . LessThanToken ) { var method = < MethodDeclaration > createNode ( SyntaxKind . Method , fullStart ) ; method . name = name ; method . questionToken = questionToken ; fillSignature ( SyntaxKind . ColonToken , false , false , method ) ; parseTypeMemberSemicolon ( ) ; return finishNode ( method ) ; } else { var property = < PropertyDeclaration > createNode ( SyntaxKind . Property , fullStart ) ; property . name = name ; property . questionToken = questionToken ; property . type = parseTypeAnnotation ( ) ; parseTypeMemberSemicolon ( ) ; return finishNode ( property ) ; } } function isStartOfTypeMember ( ) { switch ( token ) { case SyntaxKind . OpenParenToken : case SyntaxKind . LessThanToken : case SyntaxKind . OpenBracketToken : return true ; default : return isLiteralPropertyName ( ) && lookAhead ( isTypeMemberWithLiteralPropertyName ) ; } } function isTypeMemberWithLiteralPropertyName ( ) { nextToken ( ) ; return token === SyntaxKind . OpenParenToken || token === SyntaxKind . LessThanToken || token === SyntaxKind . QuestionToken || token === SyntaxKind . ColonToken || canParseSemicolon ( ) ; } function parseTypeMember ( ) { switch ( token ) { case SyntaxKind . OpenParenToken : case SyntaxKind . LessThanToken : return parseSignatureMember ( SyntaxKind . CallSignature ) ; case SyntaxKind . OpenBracketToken : return isIndexSignature ( ) ? parseIndexSignatureDeclaration ( scanner . getStartPos ( ) , undefined ) : parsePropertyOrMethodSignature ( ) ; case SyntaxKind . NewKeyword : if ( lookAhead ( isStartOfConstructSignature ) ) { return parseSignatureMember ( SyntaxKind . ConstructSignature ) ; } case SyntaxKind . StringLiteral : case SyntaxKind . NumericLiteral : return parsePropertyOrMethodSignature ( ) ; default : if ( isIdentifierOrKeyword ( ) ) { return parsePropertyOrMethodSignature ( ) ; } } } function isStartOfConstructSignature ( ) { nextToken ( ) ; return token === SyntaxKind . OpenParenToken || token === SyntaxKind . LessThanToken ; } function parseTypeLiteral ( ) { var node = < TypeLiteralNode > createNode ( SyntaxKind . TypeLiteral ) ; node . members = parseObjectTypeMembers ( ) ; return finishNode ( node ) ; } function parseObjectTypeMembers ( ) { var members ; if ( parseExpected ( SyntaxKind . OpenBraceToken ) ) { members = parseList ( ParsingContext . TypeMembers , false , parseTypeMember ) ; parseExpected ( SyntaxKind . CloseBraceToken ) ; } else { members = createMissingList < Declaration > ( ) ; } return members ; } function parseTupleType ( ) { var node = < TupleTypeNode > createNode ( SyntaxKind . TupleType ) ; node . elementTypes = parseBracketedList ( ParsingContext . TupleElementTypes , parseType , SyntaxKind . OpenBracketToken , SyntaxKind . CloseBracketToken ) ; return finishNode ( node ) ; } function parseParenthesizedType ( ) { var node = < ParenthesizedTypeNode > createNode ( SyntaxKind . ParenthesizedType ) ; parseExpected ( SyntaxKind . OpenParenToken ) ; node . type = parseType ( ) ; parseExpected ( SyntaxKind . CloseParenToken ) ; return finishNode ( node ) ; } function parseFunctionOrConstructorType ( kind ) { var node = < FunctionOrConstructorTypeNode > createNode ( kind ) ; if ( kind === SyntaxKind . ConstructorType ) { parseExpected ( SyntaxKind . NewKeyword ) ; } fillSignature ( SyntaxKind . EqualsGreaterThanToken , false , false , node ) ; return finishNode ( node ) ; } function parseKeywordAndNoDot ( ) { var node = parseTokenNode < TypeNode > ( ) ; return token === SyntaxKind . DotToken ? undefined : node ; } function parseNonArrayType ( ) { switch ( token ) { case SyntaxKind . AnyKeyword : case SyntaxKind . StringKeyword : case SyntaxKind . NumberKeyword : case SyntaxKind . BooleanKeyword : var node = tryParse ( parseKeywordAndNoDot ) ; return node || parseTypeReference ( ) ; case SyntaxKind . VoidKeyword : return parseTokenNode < TypeNode > ( ) ; case SyntaxKind . TypeOfKeyword : return parseTypeQuery ( ) ; case SyntaxKind . OpenBraceToken : return parseTypeLiteral ( ) ; case SyntaxKind . OpenBracketToken : return parseTupleType ( ) ; case SyntaxKind . OpenParenToken : return parseParenthesizedType ( ) ; default : return parseTypeReference ( ) ; } } function isStartOfType ( ) { switch ( token ) { case SyntaxKind . AnyKeyword : case SyntaxKind . StringKeyword : case SyntaxKind . NumberKeyword : case SyntaxKind . BooleanKeyword : case SyntaxKind . VoidKeyword : case SyntaxKind . TypeOfKeyword : case SyntaxKind . OpenBraceToken : case SyntaxKind . OpenBracketToken : case SyntaxKind . LessThanToken : case SyntaxKind . NewKeyword : return true ; case SyntaxKind . OpenParenToken : return lookAhead ( isStartOfParenthesizedOrFunctionType ) ; default : return isIdentifier ( ) ; } } function isStartOfParenthesizedOrFunctionType ( ) { nextToken ( ) ; return token === SyntaxKind . CloseParenToken || isStartOfParameter ( ) || isStartOfType ( ) ; } function parseArrayTypeOrHigher ( ) { var type = parseNonArrayType ( ) ; while ( ! scanner . hasPrecedingLineBreak ( ) && parseOptional ( SyntaxKind . OpenBracketToken ) ) { parseExpected ( SyntaxKind . CloseBracketToken ) ; var node = < ArrayTypeNode > createNode ( SyntaxKind . ArrayType , type . pos ) ; node . elementType = type ; type = finishNode ( node ) ; } return type ; } function parseUnionTypeOrHigher ( ) { var type = parseArrayTypeOrHigher ( ) ; if ( token === SyntaxKind . BarToken ) { var types = < NodeArray < TypeNode > > [ type ] ; types . pos = type . pos ; while ( parseOptional ( SyntaxKind . BarToken ) ) { types . push ( parseArrayTypeOrHigher ( ) ) ; } types . end = getNodeEnd ( ) ; var node = < UnionTypeNode > createNode ( SyntaxKind . UnionType , type . pos ) ; node . types = types ; type = finishNode ( node ) ; } return type ; } function isStartOfFunctionType ( ) { if ( token === SyntaxKind . LessThanToken ) { return true ; } return token === SyntaxKind . OpenParenToken && lookAhead ( isUnambiguouslyStartOfFunctionType ) ; } function isUnambiguouslyStartOfFunctionType ( ) { nextToken ( ) ; if ( token === SyntaxKind . CloseParenToken || token === SyntaxKind . DotDotDotToken ) { return true ; } if ( isIdentifier ( ) || isModifier ( token ) ) { nextToken ( ) ; if ( token === SyntaxKind . ColonToken || token === SyntaxKind . CommaToken || token === SyntaxKind . QuestionToken || token === SyntaxKind . EqualsToken || isIdentifier ( ) || isModifier ( token ) ) { return true ; } if ( token === SyntaxKind . CloseParenToken ) { nextToken ( ) ; if ( token === SyntaxKind . EqualsGreaterThanToken ) { return true ; } } } return false ; } function parseType ( ) { var savedYieldContext = inYieldContext ( ) ; var savedGeneratorParameterContext = inGeneratorParameterContext ( ) ; setYieldContext ( false ) ; setGeneratorParameterContext ( false ) ; var result = parseTypeWorker ( ) ; setYieldContext ( savedYieldContext ) ; setGeneratorParameterContext ( savedGeneratorParameterContext ) ; return result ; } function parseTypeWorker ( ) { if ( isStartOfFunctionType ( ) ) { return parseFunctionOrConstructorType ( SyntaxKind . FunctionType ) ; } if ( token === SyntaxKind . NewKeyword ) { return parseFunctionOrConstructorType ( SyntaxKind . ConstructorType ) ; } return parseUnionTypeOrHigher ( ) ; } function parseTypeAnnotation ( ) { return parseOptional ( SyntaxKind . ColonToken ) ? parseType ( ) : undefined ; } function isStartOfExpression ( ) { switch ( token ) { case SyntaxKind . ThisKeyword : case SyntaxKind . SuperKeyword : case SyntaxKind . NullKeyword : case SyntaxKind . TrueKeyword : case SyntaxKind . FalseKeyword : case SyntaxKind . NumericLiteral : case SyntaxKind . StringLiteral : case SyntaxKind . NoSubstitutionTemplateLiteral : case SyntaxKind . TemplateHead : case SyntaxKind . OpenParenToken : case SyntaxKind . OpenBracketToken : case SyntaxKind . OpenBraceToken : case SyntaxKind . FunctionKeyword : case SyntaxKind . NewKeyword : case SyntaxKind . SlashToken : case SyntaxKind . SlashEqualsToken : case SyntaxKind . PlusToken : case SyntaxKind . MinusToken : case SyntaxKind . TildeToken : case SyntaxKind . ExclamationToken : case SyntaxKind . DeleteKeyword : case SyntaxKind . TypeOfKeyword : case SyntaxKind . VoidKeyword : case SyntaxKind . PlusPlusToken : case SyntaxKind . MinusMinusToken : case SyntaxKind . LessThanToken : case SyntaxKind . Identifier : case SyntaxKind . YieldKeyword : return true ; default : if ( isBinaryOperator ( ) ) { return true ; } return isIdentifier ( ) ; } } function isStartOfExpressionStatement ( ) { return token !== SyntaxKind . OpenBraceToken && token !== SyntaxKind . FunctionKeyword && isStartOfExpression ( ) ; } function parseExpression ( ) { var expr = parseAssignmentExpressionOrHigher ( ) ; while ( parseOptional ( SyntaxKind . CommaToken ) ) { expr = makeBinaryExpression ( expr , SyntaxKind . CommaToken , parseAssignmentExpressionOrHigher ( ) ) ; } return expr ; } function parseInitializer ( inParameter ) { if ( token !== SyntaxKind . EqualsToken ) { if ( scanner . hasPrecedingLineBreak ( ) || ( inParameter && token === SyntaxKind . OpenBraceToken ) || ! isStartOfExpression ( ) ) { return undefined ; } } parseExpected ( SyntaxKind . EqualsToken ) ; return parseAssignmentExpressionOrHigher ( ) ; } function parseAssignmentExpressionOrHigher ( ) { if ( isYieldExpression ( ) ) { return parseYieldExpression ( ) ; } var arrowExpression = tryParseParenthesizedArrowFunctionExpression ( ) ; if ( arrowExpression ) { return arrowExpression ; } var expr = parseBinaryExpressionOrHigher ( 0 ) ; if ( expr . kind === SyntaxKind . Identifier && token === SyntaxKind . EqualsGreaterThanToken ) { return parseSimpleArrowFunctionExpression ( < Identifier > expr ) ; } if ( isLeftHandSideExpression ( expr ) && isAssignmentOperator ( reScanGreaterToken ( ) ) ) { var operator = token ; nextToken ( ) ; return makeBinaryExpression ( expr , operator , parseAssignmentExpressionOrHigher ( ) ) ; } return parseConditionalExpressionRest ( expr ) ; } function isYieldExpression ( ) { if ( token === SyntaxKind . YieldKeyword ) { if ( inYieldContext ( ) ) { return true ; } if ( inStrictModeContext ( ) ) { return true ; } return lookAhead ( nextTokenIsIdentifierOnSameLine ) ; } return false ; } function nextTokenIsIdentifierOnSameLine ( ) { nextToken ( ) ; return ! scanner . hasPrecedingLineBreak ( ) && isIdentifier ( ) ; } function parseYieldExpression ( ) { var node = < YieldExpression > createNode ( SyntaxKind . YieldExpression ) ; nextToken ( ) ; if ( ! scanner . hasPrecedingLineBreak ( ) && ( token === SyntaxKind . AsteriskToken || isStartOfExpression ( ) ) ) { node . asteriskToken = parseOptionalToken ( SyntaxKind . AsteriskToken ) ; node . expression = parseAssignmentExpressionOrHigher ( ) ; return finishNode ( node ) ; } else { return finishNode ( node ) ; } } function parseSimpleArrowFunctionExpression ( identifier ) { Debug . assert ( token === SyntaxKind . EqualsGreaterThanToken , "parseSimpleArrowFunctionExpression should only have been called if we had a =>" ) ; var node = < FunctionExpression > createNode ( SyntaxKind . ArrowFunction , identifier . pos ) ; var parameter = < ParameterDeclaration > createNode ( SyntaxKind . Parameter , identifier . pos ) ; parameter . name = identifier ; finishNode ( parameter ) ; node . parameters = < NodeArray < ParameterDeclaration > > [ parameter ] ; node . parameters . pos = parameter . pos ; node . parameters . end = parameter . end ; parseExpected ( SyntaxKind . EqualsGreaterThanToken ) ; node . body = parseArrowFunctionExpressionBody ( ) ; return finishNode ( node ) ; } function tryParseParenthesizedArrowFunctionExpression ( ) { var triState = isParenthesizedArrowFunctionExpression ( ) ; if ( triState === Tristate . False ) { return undefined ; } var arrowFunction = triState === Tristate . True ? parseParenthesizedArrowFunctionExpressionHead ( true ) : tryParse ( parsePossibleParenthesizedArrowFunctionExpressionHead ) ; if ( ! arrowFunction ) { return undefined ; } if ( parseExpected ( SyntaxKind . EqualsGreaterThanToken ) || token === SyntaxKind . OpenBraceToken ) { arrowFunction . body = parseArrowFunctionExpressionBody ( ) ; } else { arrowFunction . body = parseIdentifier ( ) ; } return finishNode ( arrowFunction ) ; } function isParenthesizedArrowFunctionExpression ( ) { if ( token === SyntaxKind . OpenParenToken || token === SyntaxKind . LessThanToken ) { return lookAhead ( isParenthesizedArrowFunctionExpressionWorker ) ; } if ( token === SyntaxKind . EqualsGreaterThanToken ) { return Tristate . True ; } return Tristate . False ; } function isParenthesizedArrowFunctionExpressionWorker ( ) { var first = token ; var second = nextToken ( ) ; if ( first === SyntaxKind . OpenParenToken ) { if ( second === SyntaxKind . CloseParenToken ) { var third = nextToken ( ) ; switch ( third ) { case SyntaxKind . EqualsGreaterThanToken : case SyntaxKind . ColonToken : case SyntaxKind . OpenBraceToken : return Tristate . True ; default : return Tristate . False ; } } if ( second === SyntaxKind . DotDotDotToken ) { return Tristate . True ; } if ( ! isIdentifier ( ) ) { return Tristate . False ; } if ( nextToken ( ) === SyntaxKind . ColonToken ) { return Tristate . True ; } return Tristate . Unknown ; } else { Debug . assert ( first === SyntaxKind . LessThanToken ) ; if ( ! isIdentifier ( ) ) { return Tristate . False ; } return Tristate . Unknown ; } } function parsePossibleParenthesizedArrowFunctionExpressionHead ( ) { return parseParenthesizedArrowFunctionExpressionHead ( false ) ; } function parseParenthesizedArrowFunctionExpressionHead ( allowAmbiguity ) { var node = < FunctionExpression > createNode ( SyntaxKind . ArrowFunction ) ; fillSignature ( SyntaxKind . ColonToken , false , ! allowAmbiguity , node ) ; if ( ! node . parameters ) { return undefined ; } if ( ! allowAmbiguity && token !== SyntaxKind . EqualsGreaterThanToken && token !== SyntaxKind . OpenBraceToken ) { return undefined ; } return node ; } function parseArrowFunctionExpressionBody ( ) { if ( token === SyntaxKind . OpenBraceToken ) { return parseFunctionBlock ( false , false ) ; } if ( isStatement ( true ) && ! isStartOfExpressionStatement ( ) && token !== SyntaxKind . FunctionKeyword ) { return parseFunctionBlock ( false , true ) ; } return parseAssignmentExpressionOrHigher ( ) ; } function parseConditionalExpressionRest ( leftOperand ) { if ( ! parseOptional ( SyntaxKind . QuestionToken ) ) { return leftOperand ; } var node = < ConditionalExpression > createNode ( SyntaxKind . ConditionalExpression , leftOperand . pos ) ; node . condition = leftOperand ; node . whenTrue = allowInAnd ( parseAssignmentExpressionOrHigher ) ; parseExpected ( SyntaxKind . ColonToken ) ; node . whenFalse = parseAssignmentExpressionOrHigher ( ) ; return finishNode ( node ) ; } function parseBinaryExpressionOrHigher ( precedence ) { var leftOperand = parseUnaryExpressionOrHigher ( ) ; return parseBinaryExpressionRest ( precedence , leftOperand ) ; } function parseBinaryExpressionRest ( precedence , leftOperand ) { while ( true ) { reScanGreaterToken ( ) ; var newPrecedence = getBinaryOperatorPrecedence ( ) ; if ( newPrecedence <= precedence ) { break ; } if ( token === SyntaxKind . InKeyword && inDisallowInContext ( ) ) { break ; } var operator = token ; nextToken ( ) ; leftOperand = makeBinaryExpression ( leftOperand , operator , parseBinaryExpressionOrHigher ( newPrecedence ) ) ; } return leftOperand ; } function isBinaryOperator ( ) { if ( inDisallowInContext ( ) && token === SyntaxKind . InKeyword ) { return false ; } return getBinaryOperatorPrecedence ( ) > 0 ; } function getBinaryOperatorPrecedence ( ) { switch ( token ) { case SyntaxKind . BarBarToken : return 1 ; case SyntaxKind . AmpersandAmpersandToken : return 2 ; case SyntaxKind . BarToken : return 3 ; case SyntaxKind . CaretToken : return 4 ; case SyntaxKind . AmpersandToken : return 5 ; case SyntaxKind . EqualsEqualsToken : case SyntaxKind . ExclamationEqualsToken : case SyntaxKind . EqualsEqualsEqualsToken : case SyntaxKind . ExclamationEqualsEqualsToken : return 6 ; case SyntaxKind . LessThanToken : case SyntaxKind . GreaterThanToken : case SyntaxKind . LessThanEqualsToken : case SyntaxKind . GreaterThanEqualsToken : case SyntaxKind . InstanceOfKeyword : case SyntaxKind . InKeyword : return 7 ; case SyntaxKind . LessThanLessThanToken : case SyntaxKind . GreaterThanGreaterThanToken : case SyntaxKind . GreaterThanGreaterThanGreaterThanToken : return 8 ; case SyntaxKind . PlusToken : case SyntaxKind . MinusToken : return 9 ; case SyntaxKind . AsteriskToken : case SyntaxKind . SlashToken : case SyntaxKind . PercentToken : return 10 ; } return - 1 ; } function makeBinaryExpression ( left , operator , right ) { var node = < BinaryExpression > createNode ( SyntaxKind . BinaryExpression , left . pos ) ; node . left = left ; node . operator = operator ; node . right = right ; return finishNode ( node ) ; } function parsePrefixUnaryExpression ( ) { var node = < PrefixUnaryExpression > createNode ( SyntaxKind . PrefixUnaryExpression ) ; node . operator = token ; nextToken ( ) ; node . operand = parseUnaryExpressionOrHigher ( ) ; return finishNode ( node ) ; } function parseDeleteExpression ( ) { var node = < DeleteExpression > createNode ( SyntaxKind . DeleteExpression ) ; nextToken ( ) ; node . expression = parseUnaryExpressionOrHigher ( ) ; return finishNode ( node ) ; } function parseTypeOfExpression ( ) { var node = < TypeOfExpression > createNode ( SyntaxKind . TypeOfExpression ) ; nextToken ( ) ; node . expression = parseUnaryExpressionOrHigher ( ) ; return finishNode ( node ) ; } function parseVoidExpression ( ) { var node = < VoidExpression > createNode ( SyntaxKind . VoidExpression ) ; nextToken ( ) ; node . expression = parseUnaryExpressionOrHigher ( ) ; return finishNode ( node ) ; } function parseUnaryExpressionOrHigher ( ) { switch ( token ) { case SyntaxKind . PlusToken : case SyntaxKind . MinusToken : case SyntaxKind . TildeToken : case SyntaxKind . ExclamationToken : case SyntaxKind . PlusPlusToken : case SyntaxKind . MinusMinusToken : return parsePrefixUnaryExpression ( ) ; case SyntaxKind . DeleteKeyword : return parseDeleteExpression ( ) ; case SyntaxKind . TypeOfKeyword : return parseTypeOfExpression ( ) ; case SyntaxKind . VoidKeyword : return parseVoidExpression ( ) ; case SyntaxKind . LessThanToken : return parseTypeAssertion ( ) ; default : return parsePostfixExpressionOrHigher ( ) ; } } function parsePostfixExpressionOrHigher ( ) { var expression = parseLeftHandSideExpressionOrHigher ( ) ; Debug . assert ( isLeftHandSideExpression ( expression ) ) ; if ( ( token === SyntaxKind . PlusPlusToken || token === SyntaxKind . MinusMinusToken ) && ! scanner . hasPrecedingLineBreak ( ) ) { var node = < PostfixUnaryExpression > createNode ( SyntaxKind . PostfixUnaryExpression , expression . pos ) ; node . operand = expression ; node . operator = token ; nextToken ( ) ; return finishNode ( node ) ; } return expression ; } function parseLeftHandSideExpressionOrHigher ( ) { var expression = token === SyntaxKind . SuperKeyword ? parseSuperExpression ( ) : parseMemberExpressionOrHigher ( ) ; return parseCallExpressionRest ( expression ) ; } function parseMemberExpressionOrHigher ( ) { var expression = parsePrimaryExpression ( ) ; return parseMemberExpressionRest ( expression ) ; } function parseSuperExpression ( ) { var expression = parseTokenNode < PrimaryExpression > ( ) ; if ( token === SyntaxKind . OpenParenToken || token === SyntaxKind . DotToken ) { return expression ; } var node = < PropertyAccessExpression > createNode ( SyntaxKind . PropertyAccessExpression , expression . pos ) ; node . expression = expression ; parseExpected ( SyntaxKind . DotToken , Diagnostics . super_must_be_followed_by_an_argument_list_or_member_access ) ; node . name = parseRightSideOfDot ( true ) ; return finishNode ( node ) ; } function parseTypeAssertion ( ) { var node = < TypeAssertion > createNode ( SyntaxKind . TypeAssertionExpression ) ; parseExpected ( SyntaxKind . LessThanToken ) ; node . type = parseType ( ) ; parseExpected ( SyntaxKind . GreaterThanToken ) ; node . expression = parseUnaryExpressionOrHigher ( ) ; return finishNode ( node ) ; } function parseMemberExpressionRest ( expression ) { while ( true ) { var dotOrBracketStart = scanner . getTokenPos ( ) ; if ( parseOptional ( SyntaxKind . DotToken ) ) { var propertyAccess = < PropertyAccessExpression > createNode ( SyntaxKind . PropertyAccessExpression , expression . pos ) ; propertyAccess . expression = expression ; propertyAccess . name = parseRightSideOfDot ( true ) ; expression = finishNode ( propertyAccess ) ; continue ; } if ( parseOptional ( SyntaxKind . OpenBracketToken ) ) { var indexedAccess = < ElementAccessExpression > createNode ( SyntaxKind . ElementAccessExpression , expression . pos ) ; indexedAccess . expression = expression ; if ( token !== SyntaxKind . CloseBracketToken ) { indexedAccess . argumentExpression = allowInAnd ( parseExpression ) ; if ( indexedAccess . argumentExpression . kind === SyntaxKind . StringLiteral || indexedAccess . argumentExpression . kind === SyntaxKind . NumericLiteral ) { var literal = < LiteralExpression > indexedAccess . argumentExpression ; literal . text = internIdentifier ( literal . text ) ; } } parseExpected ( SyntaxKind . CloseBracketToken ) ; expression = finishNode ( indexedAccess ) ; continue ; } if ( token === SyntaxKind . NoSubstitutionTemplateLiteral || token === SyntaxKind . TemplateHead ) { var tagExpression = < TaggedTemplateExpression > createNode ( SyntaxKind . TaggedTemplateExpression , expression . pos ) ; tagExpression . tag = expression ; tagExpression . template = token === SyntaxKind . NoSubstitutionTemplateLiteral ? parseLiteralNode ( ) : parseTemplateExpression ( ) ; expression = finishNode ( tagExpression ) ; continue ; } return < MemberExpression > expression ; } } function parseCallExpressionRest ( expression ) { while ( true ) { expression = parseMemberExpressionRest ( expression ) ; if ( token === SyntaxKind . LessThanToken ) { var typeArguments = tryParse ( parseTypeArgumentsInExpression ) ; if ( ! typeArguments ) { return expression ; } var callExpr = < CallExpression > createNode ( SyntaxKind . CallExpression , expression . pos ) ; callExpr . expression = expression ; callExpr . typeArguments = typeArguments ; callExpr . arguments = parseArgumentList ( ) ; expression = finishNode ( callExpr ) ; continue ; } else if ( token === SyntaxKind . OpenParenToken ) { var callExpr = < CallExpression > createNode ( SyntaxKind . CallExpression , expression . pos ) ; callExpr . expression = expression ; callExpr . arguments = parseArgumentList ( ) ; expression = finishNode ( callExpr ) ; continue ; } return expression ; } } function parseArgumentList ( ) { parseExpected ( SyntaxKind . OpenParenToken ) ; var result = parseDelimitedList ( ParsingContext . ArgumentExpressions , parseArgumentExpression ) ; parseExpected ( SyntaxKind . CloseParenToken ) ; return result ; } function parseTypeArgumentsInExpression ( ) { if ( ! parseOptional ( SyntaxKind . LessThanToken ) ) { return undefined ; } var typeArguments = parseDelimitedList ( ParsingContext . TypeArguments , parseType ) ; if ( ! parseExpected ( SyntaxKind . GreaterThanToken ) ) { return undefined ; } return typeArguments && canFollowTypeArgumentsInExpression ( ) ? typeArguments : undefined ; } function canFollowTypeArgumentsInExpression ( ) { switch ( token ) { case SyntaxKind . OpenParenToken : case SyntaxKind . DotToken : case SyntaxKind . CloseParenToken : case SyntaxKind . CloseBracketToken : case SyntaxKind . ColonToken : case SyntaxKind . SemicolonToken : case SyntaxKind . CommaToken : case SyntaxKind . QuestionToken : case SyntaxKind . EqualsEqualsToken : case SyntaxKind . EqualsEqualsEqualsToken : case SyntaxKind . ExclamationEqualsToken : case SyntaxKind . ExclamationEqualsEqualsToken : case SyntaxKind . AmpersandAmpersandToken : case SyntaxKind . BarBarToken : case SyntaxKind . CaretToken : case SyntaxKind . AmpersandToken : case SyntaxKind . BarToken : case SyntaxKind . CloseBraceToken : case SyntaxKind . EndOfFileToken : return true ; default : return false ; } } function parsePrimaryExpression ( ) { switch ( token ) { case SyntaxKind . NumericLiteral : case SyntaxKind . StringLiteral : case SyntaxKind . NoSubstitutionTemplateLiteral : return parseLiteralNode ( ) ; case SyntaxKind . ThisKeyword : case SyntaxKind . SuperKeyword : case SyntaxKind . NullKeyword : case SyntaxKind . TrueKeyword : case SyntaxKind . FalseKeyword : return parseTokenNode < PrimaryExpression > ( ) ; case SyntaxKind . OpenParenToken : return parseParenthesizedExpression ( ) ; case SyntaxKind . OpenBracketToken : return parseArrayLiteralExpression ( ) ; case SyntaxKind . OpenBraceToken : return parseObjectLiteralExpression ( ) ; case SyntaxKind . FunctionKeyword : return parseFunctionExpression ( ) ; case SyntaxKind . NewKeyword : return parseNewExpression ( ) ; case SyntaxKind . SlashToken : case SyntaxKind . SlashEqualsToken : if ( reScanSlashToken ( ) === SyntaxKind . RegularExpressionLiteral ) { return parseLiteralNode ( ) ; } break ; case SyntaxKind . TemplateHead : return parseTemplateExpression ( ) ; } return parseIdentifier ( Diagnostics . Expression_expected ) ; } function parseParenthesizedExpression ( ) { var node = < ParenthesizedExpression > createNode ( SyntaxKind . ParenthesizedExpression ) ; parseExpected ( SyntaxKind . OpenParenToken ) ; node . expression = allowInAnd ( parseExpression ) ; parseExpected ( SyntaxKind . CloseParenToken ) ; return finishNode ( node ) ; } function parseAssignmentExpressionOrOmittedExpression ( ) { return token === SyntaxKind . CommaToken ? < Expression > createNode ( SyntaxKind . OmittedExpression ) : parseAssignmentExpressionOrHigher ( ) ; } function parseArrayLiteralElement ( ) { return parseAssignmentExpressionOrOmittedExpression ( ) ; } function parseArgumentExpression ( ) { return allowInAnd ( parseAssignmentExpressionOrOmittedExpression ) ; } function parseArrayLiteralExpression ( ) { var node = < ArrayLiteralExpression > createNode ( SyntaxKind . ArrayLiteralExpression ) ; parseExpected ( SyntaxKind . OpenBracketToken ) ; if ( scanner . hasPrecedingLineBreak ( ) ) node . flags |= NodeFlags . MultiLine ; node . elements = parseDelimitedList ( ParsingContext . ArrayLiteralMembers , parseArrayLiteralElement ) ; parseExpected ( SyntaxKind . CloseBracketToken ) ; return finishNode ( node ) ; } function parseObjectLiteralElement ( ) { var fullStart = scanner . getStartPos ( ) ; var initialToken = token ; if ( parseContextualModifier ( SyntaxKind . GetKeyword ) || parseContextualModifier ( SyntaxKind . SetKeyword ) ) { var kind = initialToken === SyntaxKind . GetKeyword ? SyntaxKind . GetAccessor : SyntaxKind . SetAccessor ; return parseAccessorDeclaration ( kind , fullStart , undefined ) ; } var asteriskToken = parseOptionalToken ( SyntaxKind . AsteriskToken ) ; var tokenIsIdentifier = isIdentifier ( ) ; var nameToken = token ; var propertyName = parsePropertyName ( ) ; if ( asteriskToken || token === SyntaxKind . OpenParenToken || token === SyntaxKind . LessThanToken ) { return parseMethodDeclaration ( fullStart , undefined , asteriskToken , propertyName , undefined , true ) ; } var questionToken = parseOptionalToken ( SyntaxKind . QuestionToken ) ; if ( ( token === SyntaxKind . CommaToken || token === SyntaxKind . CloseBraceToken ) && tokenIsIdentifier ) { var shorthandDeclaration = < ShorthandPropertyAssignment > createNode ( SyntaxKind . ShorthandPropertyAssignment , fullStart ) ; shorthandDeclaration . name = < Identifier > propertyName ; shorthandDeclaration . questionToken = questionToken ; return finishNode ( shorthandDeclaration ) ; } else { var propertyAssignment = < PropertyAssignment > createNode ( SyntaxKind . PropertyAssignment , fullStart ) ; propertyAssignment . name = propertyName ; propertyAssignment . questionToken = questionToken ; parseExpected ( SyntaxKind . ColonToken ) ; propertyAssignment . initializer = allowInAnd ( parseAssignmentExpressionOrHigher ) ; return finishNode ( propertyAssignment ) ; } } function parseObjectLiteralExpression ( ) { var node = < ObjectLiteralExpression > createNode ( SyntaxKind . ObjectLiteralExpression ) ; parseExpected ( SyntaxKind . OpenBraceToken ) ; if ( scanner . hasPrecedingLineBreak ( ) ) { node . flags |= NodeFlags . MultiLine ; } node . properties = parseDelimitedList ( ParsingContext . ObjectLiteralMembers , parseObjectLiteralElement ) ; parseExpected ( SyntaxKind . CloseBraceToken ) ; return finishNode ( node ) ; } function parseFunctionExpression ( ) { var node = < FunctionExpression > createNode ( SyntaxKind . FunctionExpression ) ; parseExpected ( SyntaxKind . FunctionKeyword ) ; node . asteriskToken = parseOptionalToken ( SyntaxKind . AsteriskToken ) ; node . name = node . asteriskToken ? doInYieldContext ( parseOptionalIdentifier ) : parseOptionalIdentifier ( ) ; fillSignature ( SyntaxKind . ColonToken , ! ! node . asteriskToken , false , node ) ; node . body = parseFunctionBlock ( ! ! node . asteriskToken , false ) ; return finishNode ( node ) ; } function parseOptionalIdentifier ( ) { return isIdentifier ( ) ? parseIdentifier ( ) : undefined ; } function parseNewExpression ( ) { var node = < NewExpression > createNode ( SyntaxKind . NewExpression ) ; parseExpected ( SyntaxKind . NewKeyword ) ; node . expression = parseMemberExpressionOrHigher ( ) ; node . typeArguments = tryParse ( parseTypeArgumentsInExpression ) ; if ( node . typeArguments || token === SyntaxKind . OpenParenToken ) { node . arguments = parseArgumentList ( ) ; } return finishNode ( node ) ; } function parseBlock ( kind , ignoreMissingOpenBrace , checkForStrictMode ) { var node = < Block > createNode ( kind ) ; if ( parseExpected ( SyntaxKind . OpenBraceToken ) || ignoreMissingOpenBrace ) { node . statements = parseList ( ParsingContext . BlockStatements , checkForStrictMode , parseStatement ) ; parseExpected ( SyntaxKind . CloseBraceToken ) ; } else { node . statements = createMissingList < Statement > ( ) ; } return finishNode ( node ) ; } function parseFunctionBlock ( allowYield , ignoreMissingOpenBrace ) { var savedYieldContext = inYieldContext ( ) ; setYieldContext ( allowYield ) ; var block = parseBlock ( SyntaxKind . Block , ignoreMissingOpenBrace , true ) ; setYieldContext ( savedYieldContext ) ; return block ; } function parseEmptyStatement ( ) { var node = < Statement > createNode ( SyntaxKind . EmptyStatement ) ; parseExpected ( SyntaxKind . SemicolonToken ) ; return finishNode ( node ) ; } function parseIfStatement ( ) { var node = < IfStatement > createNode ( SyntaxKind . IfStatement ) ; parseExpected ( SyntaxKind . IfKeyword ) ; parseExpected ( SyntaxKind . OpenParenToken ) ; node . expression = allowInAnd ( parseExpression ) ; parseExpected ( SyntaxKind . CloseParenToken ) ; node . thenStatement = parseStatement ( ) ; node . elseStatement = parseOptional ( SyntaxKind . ElseKeyword ) ? parseStatement ( ) : undefined ; return finishNode ( node ) ; } function parseDoStatement ( ) { var node = < DoStatement > createNode ( SyntaxKind . DoStatement ) ; parseExpected ( SyntaxKind . DoKeyword ) ; node . statement = parseStatement ( ) ; parseExpected ( SyntaxKind . WhileKeyword ) ; parseExpected ( SyntaxKind . OpenParenToken ) ; node . expression = allowInAnd ( parseExpression ) ; parseExpected ( SyntaxKind . CloseParenToken ) ; parseOptional ( SyntaxKind . SemicolonToken ) ; return finishNode ( node ) ; } function parseWhileStatement ( ) { var node = < WhileStatement > createNode ( SyntaxKind . WhileStatement ) ; parseExpected ( SyntaxKind . WhileKeyword ) ; parseExpected ( SyntaxKind . OpenParenToken ) ; node . expression = allowInAnd ( parseExpression ) ; parseExpected ( SyntaxKind . CloseParenToken ) ; node . statement = parseStatement ( ) ; return finishNode ( node ) ; } function parseForOrForInStatement ( ) { var pos = getNodePos ( ) ; parseExpected ( SyntaxKind . ForKeyword ) ; parseExpected ( SyntaxKind . OpenParenToken ) ; if ( token !== SyntaxKind . SemicolonToken ) { if ( parseOptional ( SyntaxKind . VarKeyword ) ) { var declarations = disallowInAnd ( parseVariableDeclarationList ) ; } else if ( parseOptional ( SyntaxKind . LetKeyword ) ) { var declarations = setFlag ( disallowInAnd ( parseVariableDeclarationList ) , NodeFlags . Let ) ; } else if ( parseOptional ( SyntaxKind . ConstKeyword ) ) { var declarations = setFlag ( disallowInAnd ( parseVariableDeclarationList ) , NodeFlags . Const ) ; } else { var varOrInit = disallowInAnd ( parseExpression ) ; } } var forOrForInStatement ; if ( parseOptional ( SyntaxKind . InKeyword ) ) { var forInStatement = < ForInStatement > createNode ( SyntaxKind . ForInStatement , pos ) ; if ( declarations ) { forInStatement . declarations = declarations ; } else { forInStatement . variable = varOrInit ; } forInStatement . expression = allowInAnd ( parseExpression ) ; parseExpected ( SyntaxKind . CloseParenToken ) ; forOrForInStatement = forInStatement ; } else { var forStatement = < ForStatement > createNode ( SyntaxKind . ForStatement , pos ) ; if ( declarations ) { forStatement . declarations = declarations ; } if ( varOrInit ) { forStatement . initializer = varOrInit ; } parseExpected ( SyntaxKind . SemicolonToken ) ; if ( token !== SyntaxKind . SemicolonToken && token !== SyntaxKind . CloseParenToken ) { forStatement . condition = allowInAnd ( parseExpression ) ; } parseExpected ( SyntaxKind . SemicolonToken ) ; if ( token !== SyntaxKind . CloseParenToken ) { forStatement . iterator = allowInAnd ( parseExpression ) ; } parseExpected ( SyntaxKind . CloseParenToken ) ; forOrForInStatement = forStatement ; } forOrForInStatement . statement = parseStatement ( ) ; return finishNode ( forOrForInStatement ) ; } function parseBreakOrContinueStatement ( kind ) { var node = < BreakOrContinueStatement > createNode ( kind ) ; parseExpected ( kind === SyntaxKind . BreakStatement ? SyntaxKind . BreakKeyword : SyntaxKind . ContinueKeyword ) ; if ( ! canParseSemicolon ( ) ) { node . label = parseIdentifier ( ) ; } parseSemicolon ( ) ; return finishNode ( node ) ; } function parseReturnStatement ( ) { var node = < ReturnStatement > createNode ( SyntaxKind . ReturnStatement ) ; parseExpected ( SyntaxKind . ReturnKeyword ) ; if ( ! canParseSemicolon ( ) ) { node . expression = allowInAnd ( parseExpression ) ; } parseSemicolon ( ) ; return finishNode ( node ) ; } function parseWithStatement ( ) { var node = < WithStatement > createNode ( SyntaxKind . WithStatement ) ; parseExpected ( SyntaxKind . WithKeyword ) ; parseExpected ( SyntaxKind . OpenParenToken ) ; node . expression = allowInAnd ( parseExpression ) ; parseExpected ( SyntaxKind . CloseParenToken ) ; node . statement = parseStatement ( ) ; return finishNode ( node ) ; } function parseCaseClause ( ) { var node = < CaseClause > createNode ( SyntaxKind . CaseClause ) ; parseExpected ( SyntaxKind . CaseKeyword ) ; node . expression = allowInAnd ( parseExpression ) ; parseExpected ( SyntaxKind . ColonToken ) ; node . statements = parseList ( ParsingContext . SwitchClauseStatements , false , parseStatement ) ; return finishNode ( node ) ; } function parseDefaultClause ( ) { var node = < DefaultClause > createNode ( SyntaxKind . DefaultClause ) ; parseExpected ( SyntaxKind . DefaultKeyword ) ; parseExpected ( SyntaxKind . ColonToken ) ; node . statements = parseList ( ParsingContext . SwitchClauseStatements , false , parseStatement ) ; return finishNode ( node ) ; } function parseCaseOrDefaultClause ( ) { return token === SyntaxKind . CaseKeyword ? parseCaseClause ( ) : parseDefaultClause ( ) ; } function parseSwitchStatement ( ) { var node = < SwitchStatement > createNode ( SyntaxKind . SwitchStatement ) ; parseExpected ( SyntaxKind . SwitchKeyword ) ; parseExpected ( SyntaxKind . OpenParenToken ) ; node . expression = allowInAnd ( parseExpression ) ; parseExpected ( SyntaxKind . CloseParenToken ) ; parseExpected ( SyntaxKind . OpenBraceToken ) ; node . clauses = parseList ( ParsingContext . SwitchClauses , false , parseCaseOrDefaultClause ) ; parseExpected ( SyntaxKind . CloseBraceToken ) ; return finishNode ( node ) ; } function parseThrowStatement ( ) { var node = < ThrowStatement > createNode ( SyntaxKind . ThrowStatement ) ; parseExpected ( SyntaxKind . ThrowKeyword ) ; node . expression = scanner . hasPrecedingLineBreak ( ) ? undefined : allowInAnd ( parseExpression ) ; parseSemicolon ( ) ; return finishNode ( node ) ; } function parseTryStatement ( ) { var node = < TryStatement > createNode ( SyntaxKind . TryStatement ) ; node . tryBlock = parseTokenAndBlock ( SyntaxKind . TryKeyword ) ; node . catchClause = token === SyntaxKind . CatchKeyword ? parseCatchClause ( ) : undefined ; node . finallyBlock = ! node . catchClause || token === SyntaxKind . FinallyKeyword ? parseTokenAndBlock ( SyntaxKind . FinallyKeyword ) : undefined ; return finishNode ( node ) ; } function parseTokenAndBlock ( token ) { var pos = getNodePos ( ) ; parseExpected ( token ) ; var result = parseBlock ( token === SyntaxKind . TryKeyword ? SyntaxKind . TryBlock : SyntaxKind . FinallyBlock , false , false ) ; result . pos = pos ; return result ; } function parseCatchClause ( ) { var result = < CatchClause > createNode ( SyntaxKind . CatchClause ) ; parseExpected ( SyntaxKind . CatchKeyword ) ; parseExpected ( SyntaxKind . OpenParenToken ) ; result . name = parseIdentifier ( ) ; result . type = parseTypeAnnotation ( ) ; parseExpected ( SyntaxKind . CloseParenToken ) ; result . block = parseBlock ( SyntaxKind . Block , false , false ) ; return finishNode ( result ) ; } function parseDebuggerStatement ( ) { var node = < Statement > createNode ( SyntaxKind . DebuggerStatement ) ; parseExpected ( SyntaxKind . DebuggerKeyword ) ; parseSemicolon ( ) ; return finishNode ( node ) ; } function isLabel ( ) { return isIdentifier ( ) && lookAhead ( nextTokenIsColonToken ) ; } function nextTokenIsColonToken ( ) { return nextToken ( ) === SyntaxKind . ColonToken ; } function parseLabeledStatement ( ) { var node = < LabeledStatement > createNode ( SyntaxKind . LabeledStatement ) ; node . label = parseIdentifier ( ) ; parseExpected ( SyntaxKind . ColonToken ) ; node . statement = parseStatement ( ) ; return finishNode ( node ) ; } function parseExpressionStatement ( ) { var node = < ExpressionStatement > createNode ( SyntaxKind . ExpressionStatement ) ; node . expression = allowInAnd ( parseExpression ) ; parseSemicolon ( ) ; return finishNode ( node ) ; } function isStatement ( inErrorRecovery ) { switch ( token ) { case SyntaxKind . SemicolonToken : return ! inErrorRecovery ; case SyntaxKind . OpenBraceToken : case SyntaxKind . VarKeyword : case SyntaxKind . LetKeyword : case SyntaxKind . FunctionKeyword : case SyntaxKind . IfKeyword : case SyntaxKind . DoKeyword : case SyntaxKind . WhileKeyword : case SyntaxKind . ForKeyword : case SyntaxKind . ContinueKeyword : case SyntaxKind . BreakKeyword : case SyntaxKind . ReturnKeyword : case SyntaxKind . WithKeyword : case SyntaxKind . SwitchKeyword : case SyntaxKind . ThrowKeyword : case SyntaxKind . TryKeyword : case SyntaxKind . DebuggerKeyword : case SyntaxKind . CatchKeyword : case SyntaxKind . FinallyKeyword : return true ; case SyntaxKind . ConstKeyword : var isConstEnum = lookAhead ( nextTokenIsEnumKeyword ) ; return ! isConstEnum ; case SyntaxKind . InterfaceKeyword : case SyntaxKind . ClassKeyword : case SyntaxKind . ModuleKeyword : case SyntaxKind . EnumKeyword : case SyntaxKind . TypeKeyword : if ( isDeclarationStart ( ) ) { return false ; } case SyntaxKind . PublicKeyword : case SyntaxKind . PrivateKeyword : case SyntaxKind . ProtectedKeyword : case SyntaxKind . StaticKeyword : if ( lookAhead ( nextTokenIsIdentifierOrKeywordOnSameLine ) ) { return false ; } default : return isStartOfExpression ( ) ; } } function nextTokenIsEnumKeyword ( ) { nextToken ( ) ; return token === SyntaxKind . EnumKeyword ; } function nextTokenIsIdentifierOrKeywordOnSameLine ( ) { nextToken ( ) ; return isIdentifierOrKeyword ( ) && ! scanner . hasPrecedingLineBreak ( ) ; } function parseStatement ( ) { switch ( token ) { case SyntaxKind . OpenBraceToken : return parseBlock ( SyntaxKind . Block , false , false ) ; case SyntaxKind . VarKeyword : case SyntaxKind . ConstKeyword : return parseVariableStatement ( scanner . getStartPos ( ) , undefined ) ; case SyntaxKind . FunctionKeyword : return parseFunctionDeclaration ( scanner . getStartPos ( ) , undefined ) ; case SyntaxKind . SemicolonToken : return parseEmptyStatement ( ) ; case SyntaxKind . IfKeyword : return parseIfStatement ( ) ; case SyntaxKind . DoKeyword : return parseDoStatement ( ) ; case SyntaxKind . WhileKeyword : return parseWhileStatement ( ) ; case SyntaxKind . ForKeyword : return parseForOrForInStatement ( ) ; case SyntaxKind . ContinueKeyword : return parseBreakOrContinueStatement ( SyntaxKind . ContinueStatement ) ; case SyntaxKind . BreakKeyword : return parseBreakOrContinueStatement ( SyntaxKind . BreakStatement ) ; case SyntaxKind . ReturnKeyword : return parseReturnStatement ( ) ; case SyntaxKind . WithKeyword : return parseWithStatement ( ) ; case SyntaxKind . SwitchKeyword : return parseSwitchStatement ( ) ; case SyntaxKind . ThrowKeyword : return parseThrowStatement ( ) ; case SyntaxKind . TryKeyword : case SyntaxKind . CatchKeyword : case SyntaxKind . FinallyKeyword : return parseTryStatement ( ) ; case SyntaxKind . DebuggerKeyword : return parseDebuggerStatement ( ) ; case SyntaxKind . LetKeyword : if ( isLetDeclaration ( ) ) { return parseVariableStatement ( scanner . getStartPos ( ) , undefined ) ; } default : return isLabel ( ) ? parseLabeledStatement ( ) : parseExpressionStatement ( ) ; } } function parseFunctionBlockOrSemicolon ( isGenerator ) { if ( token === SyntaxKind . OpenBraceToken ) { return parseFunctionBlock ( isGenerator , false ) ; } parseSemicolon ( Diagnostics . or_expected ) ; return undefined ; } function parseVariableDeclaration ( ) { var node = < VariableDeclaration > createNode ( SyntaxKind . VariableDeclaration ) ; node . name = parseIdentifier ( ) ; node . type = parseTypeAnnotation ( ) ; node . initializer = parseInitializer ( false ) ; return finishNode ( node ) ; } function setFlag ( array , flag ) { for ( var i = 0 , n = array . length ; i < n ; i ++ ) { array [ i ] . flags |= flag ; } return array ; } function parseVariableDeclarationList ( ) { return parseDelimitedList ( ParsingContext . VariableDeclarations , parseVariableDeclaration ) ; } function parseVariableStatement ( fullStart , modifiers ) { var node = < VariableStatement > createNode ( SyntaxKind . VariableStatement , fullStart ) ; setModifiers ( node , modifiers ) ; if ( token === SyntaxKind . LetKeyword ) { node . flags |= NodeFlags . Let ; } else if ( token === SyntaxKind . ConstKeyword ) { node . flags |= NodeFlags . Const ; } else { Debug . assert ( token === SyntaxKind . VarKeyword ) ; } nextToken ( ) ; node . declarations = allowInAnd ( parseVariableDeclarationList ) ; setFlag ( node . declarations , node . flags ) ; parseSemicolon ( ) ; return finishNode ( node ) ; } function parseFunctionDeclaration ( fullStart , modifiers ) { var node = < FunctionDeclaration > createNode ( SyntaxKind . FunctionDeclaration , fullStart ) ; setModifiers ( node , modifiers ) ; parseExpected ( SyntaxKind . FunctionKeyword ) ; node . asteriskToken = parseOptionalToken ( SyntaxKind . AsteriskToken ) ; node . name = parseIdentifier ( ) ; fillSignature ( SyntaxKind . ColonToken , ! ! node . asteriskToken , false , node ) ; node . body = parseFunctionBlockOrSemicolon ( ! ! node . asteriskToken ) ; return finishNode ( node ) ; } function parseConstructorDeclaration ( pos , modifiers ) { var node = < ConstructorDeclaration > createNode ( SyntaxKind . Constructor , pos ) ; setModifiers ( node , modifiers ) ; parseExpected ( SyntaxKind . ConstructorKeyword ) ; fillSignature ( SyntaxKind . ColonToken , false , false , node ) ; node . body = parseFunctionBlockOrSemicolon ( false ) ; return finishNode ( node ) ; } function parseMethodDeclaration ( fullStart , modifiers , asteriskToken , name , questionToken , requireBlock ) { var method = < MethodDeclaration > createNode ( SyntaxKind . Method , fullStart ) ; setModifiers ( method , modifiers ) ; method . asteriskToken = asteriskToken ; method . name = name ; method . questionToken = questionToken ; fillSignature ( SyntaxKind . ColonToken , ! ! asteriskToken , false , method ) ; method . body = requireBlock ? parseFunctionBlock ( ! ! asteriskToken , false ) : parseFunctionBlockOrSemicolon ( ! ! asteriskToken ) ; return finishNode ( method ) ; } function parsePropertyOrMethodDeclaration ( fullStart , modifiers ) { var asteriskToken = parseOptionalToken ( SyntaxKind . AsteriskToken ) ; var name = parsePropertyName ( ) ; var questionToken = parseOptionalToken ( SyntaxKind . QuestionToken ) ; if ( asteriskToken || token === SyntaxKind . OpenParenToken || token === SyntaxKind . LessThanToken ) { return parseMethodDeclaration ( fullStart , modifiers , asteriskToken , name , questionToken , false ) ; } else { var property = < PropertyDeclaration > createNode ( SyntaxKind . Property , fullStart ) ; setModifiers ( property , modifiers ) ; property . name = name ; property . questionToken = questionToken ; property . type = parseTypeAnnotation ( ) ; property . initializer = allowInAnd ( parseNonParameterInitializer ) ; parseSemicolon ( ) ; return finishNode ( property ) ; } } function parseNonParameterInitializer ( ) { return parseInitializer ( false ) ; } function parseAccessorDeclaration ( kind , fullStart , modifiers ) { var node = < AccessorDeclaration > createNode ( kind , fullStart ) ; setModifiers ( node , modifiers ) ; node . name = parsePropertyName ( ) ; fillSignature ( SyntaxKind . ColonToken , false , false , node ) ; node . body = parseFunctionBlockOrSemicolon ( false ) ; return finishNode ( node ) ; } function isClassMemberStart ( ) { var idToken ; while ( isModifier ( token ) ) { idToken = token ; nextToken ( ) ; } if ( token === SyntaxKind . AsteriskToken ) { return true ; } if ( isLiteralPropertyName ( ) ) { idToken = token ; nextToken ( ) ; } if ( token === SyntaxKind . OpenBracketToken ) { return true ; } if ( idToken !== undefined ) { if ( ! isKeyword ( idToken ) || idToken === SyntaxKind . SetKeyword || idToken === SyntaxKind . GetKeyword ) { return true ; } switch ( token ) { case SyntaxKind . OpenParenToken : case SyntaxKind . LessThanToken : case SyntaxKind . ColonToken : case SyntaxKind . EqualsToken : case SyntaxKind . QuestionToken : return true ; default : return canParseSemicolon ( ) ; } } return false ; } function parseModifiers ( ) { var flags = 0 ; var modifiers ; while ( true ) { var modifierStart = scanner . getStartPos ( ) ; var modifierKind = token ; if ( ! parseAnyContextualModifier ( ) ) { break ; } if ( ! modifiers ) { modifiers = < ModifiersArray > [ ] ; modifiers . pos = modifierStart ; } flags |= modifierToFlag ( modifierKind ) ; modifiers . push ( finishNode ( createNode ( modifierKind , modifierStart ) ) ) ; } if ( modifiers ) { modifiers . flags = flags ; modifiers . end = scanner . getStartPos ( ) ; } return modifiers ; } function parseClassElement ( ) { var fullStart = getNodePos ( ) ; var modifiers = parseModifiers ( ) ; if ( parseContextualModifier ( SyntaxKind . GetKeyword ) ) { return parseAccessorDeclaration ( SyntaxKind . GetAccessor , fullStart , modifiers ) ; } if ( parseContextualModifier ( SyntaxKind . SetKeyword ) ) { return parseAccessorDeclaration ( SyntaxKind . SetAccessor , fullStart , modifiers ) ; } if ( token === SyntaxKind . ConstructorKeyword ) { return parseConstructorDeclaration ( fullStart , modifiers ) ; } if ( isIndexSignature ( ) ) { return parseIndexSignatureDeclaration ( fullStart , modifiers ) ; } if ( isIdentifierOrKeyword ( ) || token === SyntaxKind . StringLiteral || token === SyntaxKind . NumericLiteral || token === SyntaxKind . AsteriskToken || token === SyntaxKind . OpenBracketToken ) { return parsePropertyOrMethodDeclaration ( fullStart , modifiers ) ; } Debug . fail ( "Should not have attempted to parse class member declaration." ) ; } function parseClassDeclaration ( fullStart , modifiers ) { var node = < ClassDeclaration > createNode ( SyntaxKind . ClassDeclaration , fullStart ) ; setModifiers ( node , modifiers ) ; parseExpected ( SyntaxKind . ClassKeyword ) ; node . name = parseIdentifier ( ) ; node . typeParameters = parseTypeParameters ( ) ; node . heritageClauses = parseHeritageClauses ( true ) ; if ( parseExpected ( SyntaxKind . OpenBraceToken ) ) { node . members = inGeneratorParameterContext ( ) ? doOutsideOfYieldContext ( parseClassMembers ) : parseClassMembers ( ) ; parseExpected ( SyntaxKind . CloseBraceToken ) ; } else { node . members = createMissingList < ClassElement > ( ) ; } return finishNode ( node ) ; } function parseHeritageClauses ( isClassHeritageClause ) { if ( isHeritageClause ( ) ) { return isClassHeritageClause && inGeneratorParameterContext ( ) ? doOutsideOfYieldContext ( parseHeritageClausesWorker ) : parseHeritageClausesWorker ( ) ; } return undefined ; } function parseHeritageClausesWorker ( ) { return parseList ( ParsingContext . HeritageClauses , false , parseHeritageClause ) ; } function parseHeritageClause ( ) { if ( token === SyntaxKind . ExtendsKeyword || token === SyntaxKind . ImplementsKeyword ) { var node = < HeritageClause > createNode ( SyntaxKind . HeritageClause ) ; node . token = token ; nextToken ( ) ; node . types = parseDelimitedList ( ParsingContext . TypeReferences , parseTypeReference ) ; return finishNode ( node ) ; } return undefined ; } function isHeritageClause ( ) { return token === SyntaxKind . ExtendsKeyword || token === SyntaxKind . ImplementsKeyword ; } function parseClassMembers ( ) { return parseList ( ParsingContext . ClassMembers , false , parseClassElement ) ; } function parseInterfaceDeclaration ( fullStart , modifiers ) { var node = < InterfaceDeclaration > createNode ( SyntaxKind . InterfaceDeclaration , fullStart ) ; setModifiers ( node , modifiers ) ; parseExpected ( SyntaxKind . InterfaceKeyword ) ; node . name = parseIdentifier ( ) ; node . typeParameters = parseTypeParameters ( ) ; node . heritageClauses = parseHeritageClauses ( false ) ; node . members = parseObjectTypeMembers ( ) ; return finishNode ( node ) ; } function parseTypeAliasDeclaration ( fullStart , modifiers ) { var node = < TypeAliasDeclaration > createNode ( SyntaxKind . TypeAliasDeclaration , fullStart ) ; setModifiers ( node , modifiers ) ; parseExpected ( SyntaxKind . TypeKeyword ) ; node . name = parseIdentifier ( ) ; parseExpected ( SyntaxKind . EqualsToken ) ; node . type = parseType ( ) ; parseSemicolon ( ) ; return finishNode ( node ) ; } function parseEnumMember ( ) { var node = < EnumMember > createNode ( SyntaxKind . EnumMember , scanner . getStartPos ( ) ) ; node . name = parsePropertyName ( ) ; node . initializer = allowInAnd ( parseNonParameterInitializer ) ; return finishNode ( node ) ; } function parseEnumDeclaration ( fullStart , modifiers ) { var node = < EnumDeclaration > createNode ( SyntaxKind . EnumDeclaration , fullStart ) ; setModifiers ( node , modifiers ) ; parseExpected ( SyntaxKind . EnumKeyword ) ; node . name = parseIdentifier ( ) ; if ( parseExpected ( SyntaxKind . OpenBraceToken ) ) { node . members = parseDelimitedList ( ParsingContext . EnumMembers , parseEnumMember ) ; parseExpected ( SyntaxKind . CloseBraceToken ) ; } else { node . members = createMissingList < EnumMember > ( ) ; } return finishNode ( node ) ; } function parseModuleBlock ( ) { var node = < ModuleBlock > createNode ( SyntaxKind . ModuleBlock , scanner . getStartPos ( ) ) ; if ( parseExpected ( SyntaxKind . OpenBraceToken ) ) { node . statements = parseList ( ParsingContext . ModuleElements , false , parseModuleElement ) ; parseExpected ( SyntaxKind . CloseBraceToken ) ; } else { node . statements = createMissingList < Statement > ( ) ; } return finishNode ( node ) ; } function parseInternalModuleTail ( fullStart , modifiers , flags ) { var node = < ModuleDeclaration > createNode ( SyntaxKind . ModuleDeclaration , fullStart ) ; setModifiers ( node , modifiers ) ; node . flags |= flags ; node . name = parseIdentifier ( ) ; node . body = parseOptional ( SyntaxKind . DotToken ) ? parseInternalModuleTail ( getNodePos ( ) , undefined , NodeFlags . Export ) : parseModuleBlock ( ) ; return finishNode ( node ) ; } function parseAmbientExternalModuleDeclaration ( fullStart , modifiers ) { var node = < ModuleDeclaration > createNode ( SyntaxKind . ModuleDeclaration , fullStart ) ; setModifiers ( node , modifiers ) ; node . name = parseLiteralNode ( true ) ; node . body = parseModuleBlock ( ) ; return finishNode ( node ) ; } function parseModuleDeclaration ( fullStart , modifiers ) { parseExpected ( SyntaxKind . ModuleKeyword ) ; return token === SyntaxKind . StringLiteral ? parseAmbientExternalModuleDeclaration ( fullStart , modifiers ) : parseInternalModuleTail ( fullStart , modifiers , modifiers ? modifiers . flags : 0 ) ; } function isExternalModuleReference ( ) { return token === SyntaxKind . RequireKeyword && lookAhead ( nextTokenIsOpenParen ) ; } function nextTokenIsOpenParen ( ) { return nextToken ( ) === SyntaxKind . OpenParenToken ; } function parseImportDeclaration ( fullStart , modifiers ) { var node = < ImportDeclaration > createNode ( SyntaxKind . ImportDeclaration , fullStart ) ; setModifiers ( node , modifiers ) ; parseExpected ( SyntaxKind . ImportKeyword ) ; node . name = parseIdentifier ( ) ; parseExpected ( SyntaxKind . EqualsToken ) ; node . moduleReference = parseModuleReference ( ) ; parseSemicolon ( ) ; return finishNode ( node ) ; } function parseModuleReference ( ) { return isExternalModuleReference ( ) ? parseExternalModuleReference ( ) : parseEntityName ( false ) ; } function parseExternalModuleReference ( ) { var node = < ExternalModuleReference > createNode ( SyntaxKind . ExternalModuleReference ) ; parseExpected ( SyntaxKind . RequireKeyword ) ; parseExpected ( SyntaxKind . OpenParenToken ) ; node . expression = parseExpression ( ) ; if ( node . expression . kind === SyntaxKind . StringLiteral ) { internIdentifier ( ( < LiteralExpression > node . expression ) . text ) ; } parseExpected ( SyntaxKind . CloseParenToken ) ; return finishNode ( node ) ; } function parseExportAssignmentTail ( fullStart , modifiers ) { var node = < ExportAssignment > createNode ( SyntaxKind . ExportAssignment , fullStart ) ; setModifiers ( node , modifiers ) ; node . exportName = parseIdentifier ( ) ; parseSemicolon ( ) ; return finishNode ( node ) ; } function isLetDeclaration ( ) { return inStrictModeContext ( ) || lookAhead ( nextTokenIsIdentifierOnSameLine ) ; } function isDeclarationStart ( ) { switch ( token ) { case SyntaxKind . VarKeyword : case SyntaxKind . ConstKeyword : case SyntaxKind . FunctionKeyword : return true ; case SyntaxKind . LetKeyword : return isLetDeclaration ( ) ; case SyntaxKind . ClassKeyword : case SyntaxKind . InterfaceKeyword : case SyntaxKind . EnumKeyword : case SyntaxKind . ImportKeyword : case SyntaxKind . TypeKeyword : return lookAhead ( nextTokenIsIdentifierOrKeyword ) ; case SyntaxKind . ModuleKeyword : return lookAhead ( nextTokenIsIdentifierOrKeywordOrStringLiteral ) ; case SyntaxKind . ExportKeyword : return lookAhead ( nextTokenIsEqualsTokenOrDeclarationStart ) ; case SyntaxKind . DeclareKeyword : case SyntaxKind . PublicKeyword : case SyntaxKind . PrivateKeyword : case SyntaxKind . ProtectedKeyword : case SyntaxKind . StaticKeyword : return lookAhead ( nextTokenIsDeclarationStart ) ; } } function isIdentifierOrKeyword ( ) { return token >= SyntaxKind . Identifier ; } function nextTokenIsIdentifierOrKeyword ( ) { nextToken ( ) ; return isIdentifierOrKeyword ( ) ; } function nextTokenIsIdentifierOrKeywordOrStringLiteral ( ) { nextToken ( ) ; return isIdentifierOrKeyword ( ) || token === SyntaxKind . StringLiteral ; } function nextTokenIsEqualsTokenOrDeclarationStart ( ) { nextToken ( ) ; return token === SyntaxKind . EqualsToken || isDeclarationStart ( ) ; } function nextTokenIsDeclarationStart ( ) { nextToken ( ) ; return isDeclarationStart ( ) ; } function parseDeclaration ( ) { var fullStart = getNodePos ( ) ; var modifiers = parseModifiers ( ) ; if ( token === SyntaxKind . ExportKeyword ) { nextToken ( ) ; if ( parseOptional ( SyntaxKind . EqualsToken ) ) { return parseExportAssignmentTail ( fullStart , modifiers ) ; } } switch ( token ) { case SyntaxKind . VarKeyword : case SyntaxKind . LetKeyword : case SyntaxKind . ConstKeyword : return parseVariableStatement ( fullStart , modifiers ) ; case SyntaxKind . FunctionKeyword : return parseFunctionDeclaration ( fullStart , modifiers ) ; case SyntaxKind . ClassKeyword : return parseClassDeclaration ( fullStart , modifiers ) ; case SyntaxKind . InterfaceKeyword : return parseInterfaceDeclaration ( fullStart , modifiers ) ; case SyntaxKind . TypeKeyword : return parseTypeAliasDeclaration ( fullStart , modifiers ) ; case SyntaxKind . EnumKeyword : return parseEnumDeclaration ( fullStart , modifiers ) ; case SyntaxKind . ModuleKeyword : return parseModuleDeclaration ( fullStart , modifiers ) ; case SyntaxKind . ImportKeyword : return parseImportDeclaration ( fullStart , modifiers ) ; default : Debug . fail ( "Mismatch between isDeclarationStart and parseDeclaration" ) ; } } function isSourceElement ( inErrorRecovery ) { return isDeclarationStart ( ) || isStatement ( inErrorRecovery ) ; } function parseSourceElement ( ) { return parseSourceElementOrModuleElement ( ) ; } function parseModuleElement ( ) { return parseSourceElementOrModuleElement ( ) ; } function parseSourceElementOrModuleElement ( ) { return isDeclarationStart ( ) ? parseDeclaration ( ) : parseStatement ( ) ; } function processReferenceComments ( ) { var triviaScanner = createScanner ( languageVersion , false , sourceText ) ; var referencedFiles = [ ] ; var amdDependencies = [ ] ; var amdModuleName ; while ( true ) { var kind = triviaScanner . scan ( ) ; if ( kind === SyntaxKind . WhitespaceTrivia || kind === SyntaxKind . NewLineTrivia || kind === SyntaxKind . MultiLineCommentTrivia ) { continue ; } if ( kind !== SyntaxKind . SingleLineCommentTrivia ) { break ; } var range = { pos : triviaScanner . getTokenPos ( ) , end : triviaScanner . getTextPos ( ) } ; var comment = sourceText . substring ( range . pos , range . end ) ; var referencePathMatchResult = getFileReferenceFromReferencePath ( comment , range ) ; if ( referencePathMatchResult ) { var fileReference = referencePathMatchResult . fileReference ; sourceFile . hasNoDefaultLib = referencePathMatchResult . isNoDefaultLib ; var diagnosticMessage = referencePathMatchResult . diagnosticMessage ; if ( fileReference ) { referencedFiles . push ( fileReference ) ; } if ( diagnosticMessage ) { sourceFile . referenceDiagnostics . push ( createFileDiagnostic ( sourceFile , range . pos , range . end - range . pos , diagnosticMessage ) ) ; } } else { var amdModuleNameRegEx = /^\/\/\/\s*<amd-module\s+name\s*=\s*('|")(.+?)\1/gim ; var amdModuleNameMatchResult = amdModuleNameRegEx . exec ( comment ) ; if ( amdModuleNameMatchResult ) { if ( amdModuleName ) { sourceFile . referenceDiagnostics . push ( createFileDiagnostic ( sourceFile , range . pos , range . end - range . pos , Diagnostics . An_AMD_module_cannot_have_multiple_name_assignments ) ) ; } amdModuleName = amdModuleNameMatchResult [ 2 ] ; } var amdDependencyRegEx = /^\/\/\/\s*<amd-dependency\s+path\s*=\s*('|")(.+?)\1/gim ; var amdDependencyMatchResult = amdDependencyRegEx . exec ( comment ) ; if ( amdDependencyMatchResult ) { amdDependencies . push ( amdDependencyMatchResult [ 2 ] ) ; } } } return { referencedFiles , amdDependencies , amdModuleName } ; } function getExternalModuleIndicator ( ) { return forEach ( sourceFile . statements , node => node . flags & NodeFlags . Export || node . kind === SyntaxKind . ImportDeclaration && ( < ImportDeclaration > node ) . moduleReference . kind === SyntaxKind . ExternalModuleReference || node . kind === SyntaxKind . ExportAssignment ? node : undefined ) ; } var syntacticDiagnostics ; function getSyntacticDiagnostics ( ) { if ( syntacticDiagnostics === undefined ) { if ( sourceFile . parseDiagnostics . length > 0 ) { syntacticDiagnostics = sourceFile . referenceDiagnostics . concat ( sourceFile . parseDiagnostics ) ; } else { checkGrammar ( sourceText , languageVersion , sourceFile ) ; syntacticDiagnostics = sourceFile . referenceDiagnostics . concat ( sourceFile . grammarDiagnostics ) ; } } Debug . assert ( syntacticDiagnostics !== undefined ) ; return syntacticDiagnostics ; } var rootNodeFlags = 0 ; if ( fileExtensionIs ( filename , ".d.ts" ) ) { rootNodeFlags = NodeFlags . DeclarationFile ; } var sourceFile = < SourceFile > createRootNode ( SyntaxKind . SourceFile , 0 , sourceText . length , rootNodeFlags ) ; sourceFile . getLineAndCharacterFromPosition = getLineAndCharacterFromSourcePosition ; sourceFile . getPositionFromLineAndCharacter = getPositionFromSourceLineAndCharacter ; sourceFile . getLineStarts = getLineStarts ; sourceFile . getSyntacticDiagnostics = getSyntacticDiagnostics ; sourceFile . filename = normalizePath ( filename ) ; sourceFile . text = sourceText ; sourceFile . referenceDiagnostics = [ ] ; sourceFile . parseDiagnostics = [ ] ; sourceFile . grammarDiagnostics = [ ] ; sourceFile . semanticDiagnostics = [ ] ; var referenceComments = processReferenceComments ( ) ; sourceFile . referencedFiles = referenceComments . referencedFiles ; sourceFile . amdDependencies = referenceComments . amdDependencies ; sourceFile . amdModuleName = referenceComments . amdModuleName ; var scanner = createScanner ( languageVersion , true , sourceText , scanError ) ; nextToken ( ) ; sourceFile . statements = parseList ( ParsingContext . SourceElements , true , parseSourceElement ) ; Debug . assert ( token === SyntaxKind . EndOfFileToken ) ; sourceFile . endOfFileToken = parseTokenNode ( ) ; sourceFile . externalModuleIndicator = getExternalModuleIndicator ( ) ; sourceFile . nodeCount = nodeCount ; sourceFile . identifierCount = identifierCount ; sourceFile . version = version ; sourceFile . isOpen = isOpen ; sourceFile . languageVersion = languageVersion ; sourceFile . identifiers = identifiers ; return sourceFile ; } function isLeftHandSideExpression ( expr ) { if ( expr ) { switch ( expr . kind ) { case SyntaxKind . PropertyAccessExpression : case SyntaxKind . ElementAccessExpression : case SyntaxKind . NewExpression : case SyntaxKind . CallExpression : case SyntaxKind . TaggedTemplateExpression : case SyntaxKind . ArrayLiteralExpression : case SyntaxKind . ParenthesizedExpression : case SyntaxKind . ObjectLiteralExpression : case SyntaxKind . FunctionExpression : case SyntaxKind . Identifier : case SyntaxKind . RegularExpressionLiteral : case SyntaxKind . NumericLiteral : case SyntaxKind . StringLiteral : case SyntaxKind . NoSubstitutionTemplateLiteral : case SyntaxKind . TemplateExpression : case SyntaxKind . FalseKeyword : case SyntaxKind . NullKeyword : case SyntaxKind . ThisKeyword : case SyntaxKind . TrueKeyword : case SyntaxKind . SuperKeyword : return true ; } } return false ; } function isAssignmentOperator ( token ) { return token >= SyntaxKind . FirstAssignment && token <= SyntaxKind . LastAssignment ; } function checkGrammar ( sourceText , languageVersion , file ) { var grammarDiagnostics = file . grammarDiagnostics ; var scanner = createScanner ( languageVersion , true , sourceText ) ; var inAmbientContext = fileExtensionIs ( file . filename , ".d.ts" ) ; var inFunctionBlock = false ; var parent ; visitNode ( file ) ; function visitNode ( node ) { var savedParent = parent ; node . parent = parent ; parent = node ; if ( ! checkModifiers ( node ) ) { var savedInFunctionBlock = inFunctionBlock ; if ( isFunctionBlock ( node ) ) { inFunctionBlock = true ; } var savedInAmbientContext = inAmbientContext ; if ( node . flags & NodeFlags . Ambient ) { inAmbientContext = true ; } checkNodeAndChildren ( node ) ; inAmbientContext = savedInAmbientContext ; inFunctionBlock = savedInFunctionBlock ; } parent = savedParent ; } function checkNodeAndChildren ( node ) { var nodeKind = node . kind ; if ( inAmbientContext && checkForStatementInAmbientContext ( node , nodeKind ) ) { return ; } if ( checkNode ( node , nodeKind ) ) { return ; } forEachChild ( node , visitNode ) ; } function checkNode ( node , nodeKind ) { switch ( nodeKind ) { case SyntaxKind . ArrowFunction : case SyntaxKind . CallSignature : case SyntaxKind . ConstructorType : case SyntaxKind . ConstructSignature : case SyntaxKind . FunctionType : return checkAnySignatureDeclaration ( < FunctionLikeDeclaration > node ) ; case SyntaxKind . BreakStatement : case SyntaxKind . ContinueStatement : return checkBreakOrContinueStatement ( < BreakOrContinueStatement > node ) ; case SyntaxKind . CallExpression : case SyntaxKind . NewExpression : return checkCallOrNewExpression ( < NewExpression > node ) ; case SyntaxKind . EnumDeclaration : return checkEnumDeclaration ( < EnumDeclaration > node ) ; case SyntaxKind . BinaryExpression : return checkBinaryExpression ( < BinaryExpression > node ) ; case SyntaxKind . CatchClause : return checkCatchClause ( < CatchClause > node ) ; case SyntaxKind . ClassDeclaration : return checkClassDeclaration ( < ClassDeclaration > node ) ; case SyntaxKind . ComputedPropertyName : return checkComputedPropertyName ( < ComputedPropertyName > node ) ; case SyntaxKind . Constructor : return checkConstructor ( < ConstructorDeclaration > node ) ; case SyntaxKind . DeleteExpression : return checkDeleteExpression ( < DeleteExpression > node ) ; case SyntaxKind . ElementAccessExpression : return checkElementAccessExpression ( < ElementAccessExpression > node ) ; case SyntaxKind . ExportAssignment : return checkExportAssignment ( < ExportAssignment > node ) ; case SyntaxKind . ExternalModuleReference : return checkExternalModuleReference ( < ExternalModuleReference > node ) ; case SyntaxKind . ForInStatement : return checkForInStatement ( < ForInStatement > node ) ; case SyntaxKind . ForStatement : return checkForStatement ( < ForStatement > node ) ; case SyntaxKind . FunctionDeclaration : return checkFunctionDeclaration ( < FunctionLikeDeclaration > node ) ; case SyntaxKind . FunctionExpression : return checkFunctionExpression ( < FunctionExpression > node ) ; case SyntaxKind . GetAccessor : return checkGetAccessor ( < MethodDeclaration > node ) ; case SyntaxKind . HeritageClause : return checkHeritageClause ( < HeritageClause > node ) ; case SyntaxKind . IndexSignature : return checkIndexSignature ( < SignatureDeclaration > node ) ; case SyntaxKind . InterfaceDeclaration : return checkInterfaceDeclaration ( < InterfaceDeclaration > node ) ; case SyntaxKind . LabeledStatement : return checkLabeledStatement ( < LabeledStatement > node ) ; case SyntaxKind . PropertyAssignment : return checkPropertyAssignment ( < PropertyAssignment > node ) ; case SyntaxKind . Method : return checkMethod ( < MethodDeclaration > node ) ; case SyntaxKind . ModuleDeclaration : return checkModuleDeclaration ( < ModuleDeclaration > node ) ; case SyntaxKind . ObjectLiteralExpression : return checkObjectLiteralExpression ( < ObjectLiteralExpression > node ) ; case SyntaxKind . NumericLiteral : return checkNumericLiteral ( < LiteralExpression > node ) ; case SyntaxKind . Parameter : return checkParameter ( < ParameterDeclaration > node ) ; case SyntaxKind . PostfixUnaryExpression : return checkPostfixUnaryExpression ( < PostfixUnaryExpression > node ) ; case SyntaxKind . PrefixUnaryExpression : return checkPrefixUnaryExpression ( < PrefixUnaryExpression > node ) ; case SyntaxKind . Property : return checkProperty ( < PropertyDeclaration > node ) ; case SyntaxKind . ReturnStatement : return checkReturnStatement ( < ReturnStatement > node ) ; case SyntaxKind . SetAccessor : return checkSetAccessor ( < MethodDeclaration > node ) ; case SyntaxKind . SourceFile : return checkSourceFile ( < SourceFile > node ) ; case SyntaxKind . ShorthandPropertyAssignment : return checkShorthandPropertyAssignment ( < ShorthandPropertyAssignment > node ) ; case SyntaxKind . SwitchStatement : return checkSwitchStatement ( < SwitchStatement > node ) ; case SyntaxKind . TaggedTemplateExpression : return checkTaggedTemplateExpression ( < TaggedTemplateExpression > node ) ; case SyntaxKind . ThrowStatement : return checkThrowStatement ( < ThrowStatement > node ) ; case SyntaxKind . TupleType : return checkTupleType ( < TupleTypeNode > node ) ; case SyntaxKind . TypeParameter : return checkTypeParameter ( < TypeParameterDeclaration > node ) ; case SyntaxKind . TypeReference : return checkTypeReference ( < TypeReferenceNode > node ) ; case SyntaxKind . VariableDeclaration : return checkVariableDeclaration ( < VariableDeclaration > node ) ; case SyntaxKind . VariableStatement : return checkVariableStatement ( < VariableStatement > node ) ; case SyntaxKind . WithStatement : return checkWithStatement ( < WithStatement > node ) ; case SyntaxKind . YieldExpression : return checkYieldExpression ( < YieldExpression > node ) ; } } function scanToken ( pos ) { var start = skipTrivia ( sourceText , pos ) ; scanner . setTextPos ( start ) ; scanner . scan ( ) ; return start ; } function grammarErrorOnFirstToken ( node , message , arg0 ? , arg1 ? , arg2 ? ) { var start = scanToken ( node . pos ) ; grammarDiagnostics . push ( createFileDiagnostic ( file , start , scanner . getTextPos ( ) - start , message , arg0 , arg1 , arg2 ) ) ; return true ; } function grammarErrorAfterFirstToken ( node , message , arg0 ? , arg1 ? , arg2 ? ) { scanToken ( node . pos ) ; grammarDiagnostics . push ( createFileDiagnostic ( file , scanner . getTextPos ( ) , 0 , message , arg0 , arg1 , arg2 ) ) ; return true ; } function grammarErrorOnNode ( node , message , arg0 ? , arg1 ? , arg2 ? ) { var span = getErrorSpanForNode ( node ) ; var start = span . end > span . pos ? skipTrivia ( file . text , span . pos ) : span . pos ; var length = span . end - start ; grammarDiagnostics . push ( createFileDiagnostic ( file , start , length , message , arg0 , arg1 , arg2 ) ) ; return true ; } function grammarErrorAtPos ( start , length , message , arg0 ? , arg1 ? , arg2 ? ) { grammarDiagnostics . push ( createFileDiagnostic ( file , start , length , message , arg0 , arg1 , arg2 ) ) ; return true ; } function reportInvalidUseInStrictMode ( node ) { var name = sourceText . substring ( skipTrivia ( sourceText , node . pos ) , node . end ) ; return grammarErrorOnNode ( node , Diagnostics . Invalid_use_of_0_in_strict_mode , name ) ; } function checkForStatementInAmbientContext ( node , kind ) { switch ( kind ) { case SyntaxKind . Block : case SyntaxKind . EmptyStatement : case SyntaxKind . IfStatement : case SyntaxKind . DoStatement : case SyntaxKind . WhileStatement : case SyntaxKind . ForStatement : case SyntaxKind . ForInStatement : case SyntaxKind . ContinueStatement : case SyntaxKind . BreakStatement : case SyntaxKind . ReturnStatement : case SyntaxKind . WithStatement : case SyntaxKind . SwitchStatement : case SyntaxKind . ThrowStatement : case SyntaxKind . TryStatement : case SyntaxKind . DebuggerStatement : case SyntaxKind . LabeledStatement : case SyntaxKind . ExpressionStatement : return grammarErrorOnFirstToken ( node , Diagnostics . Statements_are_not_allowed_in_ambient_contexts ) ; } } function checkAnySignatureDeclaration ( node ) { return checkTypeParameterList ( node . typeParameters ) || checkParameterList ( node . parameters ) ; } function checkBinaryExpression ( node ) { if ( node . parserContextFlags & ParserContextFlags . StrictMode ) { if ( isLeftHandSideExpression ( node . left ) && isAssignmentOperator ( node . operator ) ) { if ( isEvalOrArgumentsIdentifier ( node . left ) ) { return reportInvalidUseInStrictMode ( < Identifier > node . left ) ; } } } } function isIterationStatement ( node , lookInLabeledStatements ) { switch ( node . kind ) { case SyntaxKind . ForStatement : case SyntaxKind . ForInStatement : case SyntaxKind . DoStatement : case SyntaxKind . WhileStatement : return true ; case SyntaxKind . LabeledStatement : return lookInLabeledStatements && isIterationStatement ( ( < LabeledStatement > node ) . statement , lookInLabeledStatements ) ; } return false ; } function checkLabeledStatement ( node ) { var current = node . parent ; while ( current ) { if ( isAnyFunction ( current ) ) { break ; } if ( current . kind === SyntaxKind . LabeledStatement && ( < LabeledStatement > current ) . label . text === node . label . text ) { return grammarErrorOnNode ( node . label , Diagnostics . Duplicate_label_0 , getTextOfNodeFromSourceText ( sourceText , node . label ) ) ; } current = current . parent ; } } function checkBreakOrContinueStatement ( node ) { var current = node ; while ( current ) { if ( isAnyFunction ( current ) ) { return grammarErrorOnNode ( node , Diagnostics . Jump_target_cannot_cross_function_boundary ) ; } switch ( current . kind ) { case SyntaxKind . LabeledStatement : if ( node . label && ( < LabeledStatement > current ) . label . text === node . label . text ) { var isMisplacedContinueLabel = node . kind === SyntaxKind . ContinueStatement && ! isIterationStatement ( ( < LabeledStatement > current ) . statement , true ) ; if ( isMisplacedContinueLabel ) { return grammarErrorOnNode ( node , Diagnostics . A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement ) ; } return false ; } break ; case SyntaxKind . SwitchStatement : if ( node . kind === SyntaxKind . BreakStatement && ! node . label ) { return false ; } break ; default : if ( isIterationStatement ( current , false ) && ! node . label ) { return false ; } break ; } current = current . parent ; } if ( node . label ) { var message = node . kind === SyntaxKind . BreakStatement ? Diagnostics . A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement : Diagnostics . A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement ; return grammarErrorOnNode ( node , message ) ; } else { var message = node . kind === SyntaxKind . BreakStatement ? Diagnostics . A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement : Diagnostics . A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement ; return grammarErrorOnNode ( node , message ) ; } } function checkCallOrNewExpression ( node ) { return checkTypeArguments ( node . typeArguments ) || checkArguments ( node . arguments ) ; } function checkArguments ( arguments ) { return checkForDisallowedTrailingComma ( arguments ) || checkForOmittedArgument ( arguments ) ; } function checkTypeArguments ( typeArguments ) { return checkForDisallowedTrailingComma ( typeArguments ) || checkForAtLeastOneTypeArgument ( typeArguments ) ; } function checkForOmittedArgument ( arguments ) { if ( arguments ) { for ( var i = 0 , n = arguments . length ; i < n ; i ++ ) { var arg = arguments [ i ] ; if ( arg . kind === SyntaxKind . OmittedExpression ) { return grammarErrorAtPos ( arg . pos , 0 , Diagnostics . Argument_expression_expected ) ; } } } } function checkForAtLeastOneTypeArgument ( typeArguments ) { if ( typeArguments && typeArguments . length === 0 ) { var start = typeArguments . pos - "<" . length ; var end = skipTrivia ( sourceText , typeArguments . end ) + ">" . length ; return grammarErrorAtPos ( start , end - start , Diagnostics . Type_argument_list_cannot_be_empty ) ; } } function checkForDisallowedTrailingComma ( list ) { if ( list && list . hasTrailingComma ) { var start = list . end - "," . length ; var end = list . end ; return grammarErrorAtPos ( start , end - start , Diagnostics . Trailing_comma_not_allowed ) ; } } function checkCatchClause ( node ) { if ( node . type ) { var colonStart = skipTrivia ( sourceText , node . name . end ) ; return grammarErrorAtPos ( colonStart , ":" . length , Diagnostics . Catch_clause_parameter_cannot_have_a_type_annotation ) ; } if ( node . parserContextFlags & ParserContextFlags . StrictMode && isEvalOrArgumentsIdentifier ( node . name ) ) { return reportInvalidUseInStrictMode ( node . name ) ; } } function checkClassDeclaration ( node ) { return checkClassDeclarationHeritageClauses ( node ) ; } function checkClassDeclarationHeritageClauses ( node ) { var seenExtendsClause = false ; var seenImplementsClause = false ; if ( node . heritageClauses ) { for ( var i = 0 , n = node . heritageClauses . length ; i < n ; i ++ ) { Debug . assert ( i <= 2 ) ; var heritageClause = node . heritageClauses [ i ] ; if ( heritageClause . token === SyntaxKind . ExtendsKeyword ) { if ( seenExtendsClause ) { return grammarErrorOnFirstToken ( heritageClause , Diagnostics . extends_clause_already_seen ) ; } if ( seenImplementsClause ) { return grammarErrorOnFirstToken ( heritageClause , Diagnostics . extends_clause_must_precede_implements_clause ) ; } if ( heritageClause . types . length > 1 ) { return grammarErrorOnFirstToken ( heritageClause . types [ 1 ] , Diagnostics . Classes_can_only_extend_a_single_class ) ; } seenExtendsClause = true ; } else { Debug . assert ( heritageClause . token === SyntaxKind . ImplementsKeyword ) ; if ( seenImplementsClause ) { return grammarErrorOnFirstToken ( heritageClause , Diagnostics . implements_clause_already_seen ) ; } seenImplementsClause = true ; } } } return false ; } function checkForAtLeastOneHeritageClause ( types , listType ) { if ( types && types . length === 0 ) { return grammarErrorAtPos ( types . pos , 0 , Diagnostics . _0_list_cannot_be_empty , listType ) ; } } function checkConstructor ( node ) { return checkAnySignatureDeclaration ( node ) || checkConstructorTypeParameters ( node ) || checkConstructorTypeAnnotation ( node ) || checkForBodyInAmbientContext ( node . body , true ) ; } function checkConstructorTypeParameters ( node ) { if ( node . typeParameters ) { return grammarErrorAtPos ( node . typeParameters . pos , node . typeParameters . end - node . typeParameters . pos , Diagnostics . Type_parameters_cannot_appear_on_a_constructor_declaration ) ; } } function checkConstructorTypeAnnotation ( node ) { if ( node . type ) { return grammarErrorOnNode ( node . type , Diagnostics . Type_annotation_cannot_appear_on_a_constructor_declaration ) ; } } function checkDeleteExpression ( node ) { if ( node . parserContextFlags & ParserContextFlags . StrictMode && node . expression . kind === SyntaxKind . Identifier ) { return grammarErrorOnNode ( node . expression , Diagnostics . delete_cannot_be_called_on_an_identifier_in_strict_mode ) ; } } function checkEnumDeclaration ( enumDecl ) { var enumIsConst = ( enumDecl . flags & NodeFlags . Const ) !== 0 ; var hasError = false ; if ( ! enumIsConst ) { var inConstantEnumMemberSection = true ; for ( var i = 0 , n = enumDecl . members . length ; i < n ; i ++ ) { var node = enumDecl . members [ i ] ; if ( node . name . kind === SyntaxKind . ComputedPropertyName ) { hasError = grammarErrorOnNode ( node . name , Diagnostics . Computed_property_names_are_not_allowed_in_enums ) ; } else if ( inAmbientContext ) { if ( node . initializer && ! isIntegerLiteral ( node . initializer ) ) { hasError = grammarErrorOnNode ( node . name , Diagnostics . Ambient_enum_elements_can_only_have_integer_literal_initializers ) || hasError ; } } else if ( node . initializer ) { inConstantEnumMemberSection = isIntegerLiteral ( node . initializer ) ; } else if ( ! inConstantEnumMemberSection ) { hasError = grammarErrorOnNode ( node . name , Diagnostics . Enum_member_must_have_initializer ) || hasError ; } } } return hasError ; } function isIntegerLiteral ( expression ) { function isInteger ( literalExpression ) { return /^[0-9]+([eE]\+?[0-9]+)?$/ . test ( literalExpression . text ) ; } if ( expression . kind === SyntaxKind . PrefixUnaryExpression ) { var unaryExpression = < PrefixUnaryExpression > expression ; if ( unaryExpression . operator === SyntaxKind . PlusToken || unaryExpression . operator === SyntaxKind . MinusToken ) { expression = unaryExpression . operand ; } } if ( expression . kind === SyntaxKind . NumericLiteral ) { return isInteger ( < LiteralExpression > expression ) ; } return false ; } function checkExportAssignment ( node ) { if ( node . flags & NodeFlags . Modifier ) { return grammarErrorOnFirstToken ( node , Diagnostics . An_export_assignment_cannot_have_modifiers ) ; } } function checkExternalModuleReference ( node ) { if ( node . expression . kind !== SyntaxKind . StringLiteral ) { return grammarErrorOnNode ( node . expression , Diagnostics . String_literal_expected ) ; } } function checkForInStatement ( node ) { return checkVariableDeclarations ( node . declarations ) || checkForMoreThanOneDeclaration ( node . declarations ) ; } function checkForStatement ( node ) { return checkVariableDeclarations ( node . declarations ) ; } function checkForMoreThanOneDeclaration ( declarations ) { if ( declarations && declarations . length > 1 ) { return grammarErrorOnFirstToken ( declarations [ 1 ] , Diagnostics . Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement ) ; } } function checkFunctionDeclaration ( node ) { return checkAnySignatureDeclaration ( node ) || checkFunctionName ( node . name ) || checkForBodyInAmbientContext ( node . body , false ) || checkForGenerator ( node ) ; } function checkForGenerator ( node ) { if ( node . asteriskToken ) { return grammarErrorOnNode ( node . asteriskToken , Diagnostics . Generators_are_not_currently_supported ) ; } } function checkFunctionExpression ( node ) { return checkAnySignatureDeclaration ( node ) || checkFunctionName ( node . name ) || checkForGenerator ( node ) ; } function checkFunctionName ( name ) { if ( name && name . parserContextFlags & ParserContextFlags . StrictMode && isEvalOrArgumentsIdentifier ( name ) ) { return reportInvalidUseInStrictMode ( < Identifier > name ) ; } } function checkGetAccessor ( node ) { return checkAnySignatureDeclaration ( node ) || checkAccessor ( node ) ; } function checkElementAccessExpression ( node ) { if ( ! node . argumentExpression ) { if ( node . parent . kind === SyntaxKind . NewExpression && ( < NewExpression > node . parent ) . expression === node ) { var start = skipTrivia ( sourceText , node . expression . end ) ; var end = node . end ; return grammarErrorAtPos ( start , end - start , Diagnostics . new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead ) ; } else { var start = node . end - "]" . length ; var end = node . end ; return grammarErrorAtPos ( start , end - start , Diagnostics . Expression_expected ) ; } } } function checkHeritageClause ( node ) { return checkForDisallowedTrailingComma ( node . types ) || checkForAtLeastOneHeritageClause ( node . types , tokenToString ( node . token ) ) ; } function checkIndexSignature ( node ) { return checkIndexSignatureParameters ( node ) || checkForIndexSignatureModifiers ( node ) ; } function checkForIndexSignatureModifiers ( node ) { if ( node . flags & NodeFlags . Modifier ) { return grammarErrorOnFirstToken ( node , Diagnostics . Modifiers_not_permitted_on_index_signature_members ) ; } } function checkIndexSignatureParameters ( node ) { var parameter = node . parameters [ 0 ] ; if ( node . parameters . length !== 1 ) { if ( parameter ) { return grammarErrorOnNode ( parameter . name , Diagnostics . An_index_signature_must_have_exactly_one_parameter ) ; } else { return grammarErrorOnNode ( node , Diagnostics . An_index_signature_must_have_exactly_one_parameter ) ; } } else if ( parameter . dotDotDotToken ) { return grammarErrorOnNode ( parameter . dotDotDotToken , Diagnostics . An_index_signature_cannot_have_a_rest_parameter ) ; } else if ( parameter . flags & NodeFlags . Modifier ) { return grammarErrorOnNode ( parameter . name , Diagnostics . An_index_signature_parameter_cannot_have_an_accessibility_modifier ) ; } else if ( parameter . questionToken ) { return grammarErrorOnNode ( parameter . questionToken , Diagnostics . An_index_signature_parameter_cannot_have_a_question_mark ) ; } else if ( parameter . initializer ) { return grammarErrorOnNode ( parameter . name , Diagnostics . An_index_signature_parameter_cannot_have_an_initializer ) ; } else if ( ! parameter . type ) { return grammarErrorOnNode ( parameter . name , Diagnostics . An_index_signature_parameter_must_have_a_type_annotation ) ; } else if ( parameter . type . kind !== SyntaxKind . StringKeyword && parameter . type . kind !== SyntaxKind . NumberKeyword ) { return grammarErrorOnNode ( parameter . name , Diagnostics . An_index_signature_parameter_type_must_be_string_or_number ) ; } else if ( ! node . type ) { return grammarErrorOnNode ( node , Diagnostics . An_index_signature_must_have_a_type_annotation ) ; } } function checkInterfaceDeclaration ( node ) { return checkInterfaceDeclarationHeritageClauses ( node ) ; } function checkInterfaceDeclarationHeritageClauses ( node ) { var seenExtendsClause = false ; if ( node . heritageClauses ) { for ( var i = 0 , n = node . heritageClauses . length ; i < n ; i ++ ) { Debug . assert ( i <= 1 ) ; var heritageClause = node . heritageClauses [ i ] ; if ( heritageClause . token === SyntaxKind . ExtendsKeyword ) { if ( seenExtendsClause ) { return grammarErrorOnFirstToken ( heritageClause , Diagnostics . extends_clause_already_seen ) ; } seenExtendsClause = true ; } else { Debug . assert ( heritageClause . token === SyntaxKind . ImplementsKeyword ) ; return grammarErrorOnFirstToken ( heritageClause , Diagnostics . Interface_declaration_cannot_have_implements_clause ) ; } } } return false ; } function checkMethod ( node ) { if ( checkAnySignatureDeclaration ( node ) || checkForBodyInAmbientContext ( node . body , false ) || checkForGenerator ( node ) ) { return true ; } if ( node . parent . kind === SyntaxKind . ClassDeclaration ) { if ( checkForInvalidQuestionMark ( node , node . questionToken , Diagnostics . A_class_member_cannot_be_declared_optional ) ) { return true ; } if ( inAmbientContext ) { return checkForDisallowedComputedProperty ( node . name , Diagnostics . Computed_property_names_are_not_allowed_in_an_ambient_context ) ; } else if ( ! node . body ) { return checkForDisallowedComputedProperty ( node . name , Diagnostics . Computed_property_names_are_not_allowed_in_method_overloads ) ; } } else if ( node . parent . kind === SyntaxKind . InterfaceDeclaration ) { return checkForDisallowedComputedProperty ( node . name , Diagnostics . Computed_property_names_are_not_allowed_in_interfaces ) ; } else if ( node . parent . kind === SyntaxKind . TypeLiteral ) { return checkForDisallowedComputedProperty ( node . name , Diagnostics . Computed_property_names_are_not_allowed_in_type_literals ) ; } } function checkForBodyInAmbientContext ( body , isConstructor ) { if ( inAmbientContext && body && body . kind === SyntaxKind . Block ) { var diagnostic = isConstructor ? Diagnostics . A_constructor_implementation_cannot_be_declared_in_an_ambient_context : Diagnostics . A_function_implementation_cannot_be_declared_in_an_ambient_context ; return grammarErrorOnFirstToken ( body , diagnostic ) ; } } function checkModuleDeclaration ( node ) { return checkModuleDeclarationName ( node ) || checkModuleDeclarationStatements ( node ) ; } function checkModuleDeclarationName ( node ) { if ( ! inAmbientContext && node . name . kind === SyntaxKind . StringLiteral ) { return grammarErrorOnNode ( node . name , Diagnostics . Only_ambient_modules_can_use_quoted_names ) ; } } function checkModuleDeclarationStatements ( node ) { if ( node . name . kind === SyntaxKind . Identifier && node . body . kind === SyntaxKind . ModuleBlock ) { var statements = ( < ModuleBlock > node . body ) . statements ; for ( var i = 0 , n = statements . length ; i < n ; i ++ ) { var statement = statements [ i ] ; if ( statement . kind === SyntaxKind . ExportAssignment ) { return grammarErrorOnNode ( statement , Diagnostics . An_export_assignment_cannot_be_used_in_an_internal_module ) ; } else if ( isExternalModuleImportDeclaration ( statement ) ) { return grammarErrorOnNode ( getExternalModuleImportDeclarationExpression ( statement ) , Diagnostics . Import_declarations_in_an_internal_module_cannot_reference_an_external_module ) ; } } } } function checkObjectLiteralExpression ( node ) { var seen = { } ; var Property = 1 ; var GetAccessor = 2 ; var SetAccesor = 4 ; var GetOrSetAccessor = GetAccessor | SetAccesor ; var inStrictMode = ( node . parserContextFlags & ParserContextFlags . StrictMode ) !== 0 ; for ( var i = 0 , n = node . properties . length ; i < n ; i ++ ) { var prop = < Declaration > node . properties [ i ] ; var name = < Identifier > prop . name ; if ( prop . kind === SyntaxKind . OmittedExpression || name . kind === SyntaxKind . ComputedPropertyName ) { continue ; } var currentKind ; if ( prop . kind === SyntaxKind . PropertyAssignment || prop . kind === SyntaxKind . ShorthandPropertyAssignment || prop . kind === SyntaxKind . Method ) { currentKind = Property ; } else if ( prop . kind === SyntaxKind . GetAccessor ) { currentKind = GetAccessor ; } else if ( prop . kind === SyntaxKind . SetAccessor ) { currentKind = SetAccesor ; } else { Debug . fail ( "Unexpected syntax kind:" + prop . kind ) ; } if ( ! hasProperty ( seen , name . text ) ) { seen [ name . text ] = currentKind ; } else { var existingKind = seen [ name . text ] ; if ( currentKind === Property && existingKind === Property ) { if ( inStrictMode ) { grammarErrorOnNode ( name , Diagnostics . An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode ) ; } } else if ( ( currentKind & GetOrSetAccessor ) && ( existingKind & GetOrSetAccessor ) ) { if ( existingKind !== GetOrSetAccessor && currentKind !== existingKind ) { seen [ name . text ] = currentKind | existingKind ; } else { return grammarErrorOnNode ( name , Diagnostics . An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name ) ; } } else { return grammarErrorOnNode ( name , Diagnostics . An_object_literal_cannot_have_property_and_accessor_with_the_same_name ) ; } } } } function checkNumericLiteral ( node ) { if ( node . flags & NodeFlags . OctalLiteral ) { if ( node . parserContextFlags & ParserContextFlags . StrictMode ) { return grammarErrorOnNode ( node , Diagnostics . Octal_literals_are_not_allowed_in_strict_mode ) ; } else if ( languageVersion >= ScriptTarget . ES5 ) { return grammarErrorOnNode ( node , Diagnostics . Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher ) ; } } } function checkModifiers ( node ) { switch ( node . kind ) { case SyntaxKind . GetAccessor : case SyntaxKind . SetAccessor : case SyntaxKind . Constructor : case SyntaxKind . Property : case SyntaxKind . Method : case SyntaxKind . IndexSignature : case SyntaxKind . ClassDeclaration : case SyntaxKind . InterfaceDeclaration : case SyntaxKind . ModuleDeclaration : case SyntaxKind . EnumDeclaration : case SyntaxKind . ExportAssignment : case SyntaxKind . VariableStatement : case SyntaxKind . FunctionDeclaration : case SyntaxKind . TypeAliasDeclaration : case SyntaxKind . ImportDeclaration : case SyntaxKind . Parameter : break ; default : return false ; } if ( ! node . modifiers ) { return ; } var lastStatic , lastPrivate , lastProtected , lastDeclare ; var flags = 0 ; for ( var i = 0 , n = node . modifiers . length ; i < n ; i ++ ) { var modifier = node . modifiers [ i ] ; switch ( modifier . kind ) { case SyntaxKind . PublicKeyword : case SyntaxKind . ProtectedKeyword : case SyntaxKind . PrivateKeyword : var text ; if ( modifier . kind === SyntaxKind . PublicKeyword ) { text = "public" ; } else if ( modifier . kind === SyntaxKind . ProtectedKeyword ) { text = "protected" ; lastProtected = modifier ; } else { text = "private" ; lastPrivate = modifier ; } if ( flags & NodeFlags . AccessibilityModifier ) { return grammarErrorOnNode ( modifier , Diagnostics . Accessibility_modifier_already_seen ) ; } else if ( flags & NodeFlags . Static ) { return grammarErrorOnNode ( modifier , Diagnostics . _0_modifier_must_precede_1_modifier , text , "static" ) ; } else if ( node . parent . kind === SyntaxKind . ModuleBlock || node . parent . kind === SyntaxKind . SourceFile ) { return grammarErrorOnNode ( modifier , Diagnostics . _0_modifier_cannot_appear_on_a_module_element , text ) ; } flags |= modifierToFlag ( modifier . kind ) ; break ; case SyntaxKind . StaticKeyword : if ( flags & NodeFlags . Static ) { return grammarErrorOnNode ( modifier , Diagnostics . _0_modifier_already_seen , "static" ) ; } else if ( node . parent . kind === SyntaxKind . ModuleBlock || node . parent . kind === SyntaxKind . SourceFile ) { return grammarErrorOnNode ( modifier , Diagnostics . _0_modifier_cannot_appear_on_a_module_element , "static" ) ; } else if ( node . kind === SyntaxKind . Parameter ) { return grammarErrorOnNode ( modifier , Diagnostics . _0_modifier_cannot_appear_on_a_parameter , "static" ) ; } flags |= NodeFlags . Static ; lastStatic = modifier ; break ; case SyntaxKind . ExportKeyword : if ( flags & NodeFlags . Export ) { return grammarErrorOnNode ( modifier , Diagnostics . _0_modifier_already_seen , "export" ) ; } else if ( flags & NodeFlags . Ambient ) { return grammarErrorOnNode ( modifier , Diagnostics . _0_modifier_must_precede_1_modifier , "export" , "declare" ) ; } else if ( node . parent . kind === SyntaxKind . ClassDeclaration ) { return grammarErrorOnNode ( modifier , Diagnostics . _0_modifier_cannot_appear_on_a_class_element , "export" ) ; } else if ( node . kind === SyntaxKind . Parameter ) { return grammarErrorOnNode ( modifier , Diagnostics . _0_modifier_cannot_appear_on_a_parameter , "export" ) ; } flags |= NodeFlags . Export ; break ; case SyntaxKind . DeclareKeyword : if ( flags & NodeFlags . Ambient ) { return grammarErrorOnNode ( modifier , Diagnostics . _0_modifier_already_seen , "declare" ) ; } else if ( node . parent . kind === SyntaxKind . ClassDeclaration ) { return grammarErrorOnNode ( modifier , Diagnostics . _0_modifier_cannot_appear_on_a_class_element , "declare" ) ; } else if ( node . kind === SyntaxKind . Parameter ) { return grammarErrorOnNode ( modifier , Diagnostics . _0_modifier_cannot_appear_on_a_parameter , "declare" ) ; } else if ( inAmbientContext && node . parent . kind === SyntaxKind . ModuleBlock ) { return grammarErrorOnNode ( modifier , Diagnostics . A_declare_modifier_cannot_be_used_in_an_already_ambient_context ) ; } flags |= NodeFlags . Ambient ; lastDeclare = modifier ; break ; } } if ( node . kind === SyntaxKind . Constructor ) { if ( flags & NodeFlags . Static ) { return grammarErrorOnNode ( lastStatic , Diagnostics . _0_modifier_cannot_appear_on_a_constructor_declaration , "static" ) ; } else if ( flags & NodeFlags . Protected ) { return grammarErrorOnNode ( lastProtected , Diagnostics . _0_modifier_cannot_appear_on_a_constructor_declaration , "protected" ) ; } else if ( flags & NodeFlags . Private ) { return grammarErrorOnNode ( lastPrivate , Diagnostics . _0_modifier_cannot_appear_on_a_constructor_declaration , "private" ) ; } } else if ( node . kind === SyntaxKind . ImportDeclaration && flags & NodeFlags . Ambient ) { return grammarErrorOnNode ( lastDeclare , Diagnostics . A_declare_modifier_cannot_be_used_with_an_import_declaration , "declare" ) ; } else if ( node . kind === SyntaxKind . InterfaceDeclaration && flags & NodeFlags . Ambient ) { return grammarErrorOnNode ( lastDeclare , Diagnostics . A_declare_modifier_cannot_be_used_with_an_interface_declaration , "declare" ) ; } } function checkParameter ( node ) { if ( node . parserContextFlags & ParserContextFlags . StrictMode && isEvalOrArgumentsIdentifier ( node . name ) ) { return reportInvalidUseInStrictMode ( node . name ) ; } } function checkTypeParameterList ( typeParameters ) { if ( checkForDisallowedTrailingComma ( typeParameters ) ) { return true ; } if ( typeParameters && typeParameters . length === 0 ) { var start = typeParameters . pos - "<" . length ; var end = skipTrivia ( sourceText , typeParameters . end ) + ">" . length ; return grammarErrorAtPos ( start , end - start , Diagnostics . Type_parameter_list_cannot_be_empty ) ; } } function checkParameterList ( parameters ) { if ( checkForDisallowedTrailingComma ( parameters ) ) { return true ; } var seenOptionalParameter = false ; var parameterCount = parameters . length ; for ( var i = 0 ; i < parameterCount ; i ++ ) { var parameter = parameters [ i ] ; if ( parameter . dotDotDotToken ) { if ( i !== ( parameterCount - 1 ) ) { return grammarErrorOnNode ( parameter . dotDotDotToken , Diagnostics . A_rest_parameter_must_be_last_in_a_parameter_list ) ; } if ( parameter . questionToken ) { return grammarErrorOnNode ( parameter . questionToken , Diagnostics . A_rest_parameter_cannot_be_optional ) ; } if ( parameter . initializer ) { return grammarErrorOnNode ( parameter . name , Diagnostics . A_rest_parameter_cannot_have_an_initializer ) ; } } else if ( parameter . questionToken || parameter . initializer ) { seenOptionalParameter = true ; if ( parameter . questionToken && parameter . initializer ) { return grammarErrorOnNode ( parameter . name , Diagnostics . Parameter_cannot_have_question_mark_and_initializer ) ; } } else { if ( seenOptionalParameter ) { return grammarErrorOnNode ( parameter . name , Diagnostics . A_required_parameter_cannot_follow_an_optional_parameter ) ; } } } } function checkPostfixUnaryExpression ( node ) { if ( node . parserContextFlags & ParserContextFlags . StrictMode && isEvalOrArgumentsIdentifier ( node . operand ) ) { return reportInvalidUseInStrictMode ( < Identifier > node . operand ) ; } } function checkPrefixUnaryExpression ( node ) { if ( node . parserContextFlags & ParserContextFlags . StrictMode ) { if ( ( node . operator === SyntaxKind . PlusPlusToken || node . operator === SyntaxKind . MinusMinusToken ) && isEvalOrArgumentsIdentifier ( node . operand ) ) { return reportInvalidUseInStrictMode ( < Identifier > node . operand ) ; } } } function checkProperty ( node ) { if ( node . parent . kind === SyntaxKind . ClassDeclaration ) { if ( checkForInvalidQuestionMark ( node , node . questionToken , Diagnostics . A_class_member_cannot_be_declared_optional ) || checkForDisallowedComputedProperty ( node . name , Diagnostics . Computed_property_names_are_not_allowed_in_class_property_declarations ) ) { return true ; } } else if ( node . parent . kind === SyntaxKind . InterfaceDeclaration ) { if ( checkForDisallowedComputedProperty ( node . name , Diagnostics . Computed_property_names_are_not_allowed_in_interfaces ) ) { return true ; } } else if ( node . parent . kind === SyntaxKind . TypeLiteral ) { if ( checkForDisallowedComputedProperty ( node . name , Diagnostics . Computed_property_names_are_not_allowed_in_type_literals ) ) { return true ; } } return checkForInitializerInAmbientContext ( node ) ; } function checkComputedPropertyName ( node ) { return grammarErrorOnNode ( node , Diagnostics . Computed_property_names_are_not_currently_supported ) ; if ( languageVersion < ScriptTarget . ES6 ) { return grammarErrorOnNode ( node , Diagnostics . Computed_property_names_are_only_available_when_targeting_ECMAScript_6_and_higher ) ; } else if ( node . expression . kind === SyntaxKind . BinaryExpression && ( < BinaryExpression > node . expression ) . operator === SyntaxKind . CommaToken ) { return grammarErrorOnNode ( node . expression , Diagnostics . A_comma_expression_is_not_allowed_in_a_computed_property_name ) ; } } function checkForDisallowedComputedProperty ( node , message ) { if ( node . kind === SyntaxKind . ComputedPropertyName ) { return grammarErrorOnNode ( node , message ) ; } } function checkForInitializerInAmbientContext ( node ) { if ( inAmbientContext && node . initializer ) { return grammarErrorOnFirstToken ( node . initializer , Diagnostics . Initializers_are_not_allowed_in_ambient_contexts ) ; } } function checkPropertyAssignment ( node ) { return checkForInvalidQuestionMark ( node , node . questionToken , Diagnostics . An_object_member_cannot_be_declared_optional ) ; } function checkForInvalidQuestionMark ( node , questionToken , message ) { if ( questionToken ) { return grammarErrorOnNode ( questionToken , message ) ; } } function checkReturnStatement ( node ) { if ( ! inFunctionBlock ) { return grammarErrorOnFirstToken ( node , Diagnostics . A_return_statement_can_only_be_used_within_a_function_body ) ; } } function checkSetAccessor ( node ) { return checkAnySignatureDeclaration ( node ) || checkAccessor ( node ) ; } function checkAccessor ( accessor ) { var kind = accessor . kind ; if ( languageVersion < ScriptTarget . ES5 ) { return grammarErrorOnNode ( accessor . name , Diagnostics . Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher ) ; } else if ( inAmbientContext ) { return grammarErrorOnNode ( accessor . name , Diagnostics . An_accessor_cannot_be_declared_in_an_ambient_context ) ; } else if ( accessor . body === undefined ) { return grammarErrorAtPos ( accessor . end - 1 , ";" . length , Diagnostics . _0_expected , "{" ) ; } else if ( accessor . typeParameters ) { return grammarErrorOnNode ( accessor . name , Diagnostics . An_accessor_cannot_have_type_parameters ) ; } else if ( kind === SyntaxKind . GetAccessor && accessor . parameters . length ) { return grammarErrorOnNode ( accessor . name , Diagnostics . A_get_accessor_cannot_have_parameters ) ; } else if ( kind === SyntaxKind . SetAccessor ) { if ( accessor . type ) { return grammarErrorOnNode ( accessor . name , Diagnostics . A_set_accessor_cannot_have_a_return_type_annotation ) ; } else if ( accessor . parameters . length !== 1 ) { return grammarErrorOnNode ( accessor . name , Diagnostics . A_set_accessor_must_have_exactly_one_parameter ) ; } else { var parameter = accessor . parameters [ 0 ] ; if ( parameter . dotDotDotToken ) { return grammarErrorOnNode ( parameter . dotDotDotToken , Diagnostics . A_set_accessor_cannot_have_rest_parameter ) ; } else if ( parameter . flags & NodeFlags . Modifier ) { return grammarErrorOnNode ( accessor . name , Diagnostics . A_parameter_property_is_only_allowed_in_a_constructor_implementation ) ; } else if ( parameter . questionToken ) { return grammarErrorOnNode ( parameter . questionToken , Diagnostics . A_set_accessor_cannot_have_an_optional_parameter ) ; } else if ( parameter . initializer ) { return grammarErrorOnNode ( accessor . name , Diagnostics . A_set_accessor_parameter_cannot_have_an_initializer ) ; } } } } function checkSourceFile ( node ) { return inAmbientContext && checkTopLevelElementsForRequiredDeclareModifier ( file ) ; } function checkTopLevelElementsForRequiredDeclareModifier ( file ) { for ( var i = 0 , n = file . statements . length ; i < n ; i ++ ) { var decl = file . statements [ i ] ; if ( isDeclaration ( decl ) || decl . kind === SyntaxKind . VariableStatement ) { if ( checkTopLevelElementForRequiredDeclareModifier ( decl ) ) { return true ; } } } } function checkTopLevelElementForRequiredDeclareModifier ( node ) { if ( node . kind === SyntaxKind . InterfaceDeclaration || node . kind === SyntaxKind . ImportDeclaration || node . kind === SyntaxKind . ExportAssignment || ( node . flags & NodeFlags . Ambient ) ) { return false ; } return grammarErrorOnFirstToken ( node , Diagnostics . A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file ) ; } function checkShorthandPropertyAssignment ( node ) { return checkForInvalidQuestionMark ( node , node . questionToken , Diagnostics . An_object_member_cannot_be_declared_optional ) ; } function checkSwitchStatement ( node ) { var firstDefaultClause ; for ( var i = 0 , n = node . clauses . length ; i < n ; i ++ ) { var clause = node . clauses [ i ] ; if ( clause . kind === SyntaxKind . DefaultClause ) { if ( firstDefaultClause === undefined ) { firstDefaultClause = clause ; } else { var start = skipTrivia ( file . text , clause . pos ) ; var end = clause . statements . length > 0 ? clause . statements [ 0 ] . pos : clause . end ; return grammarErrorAtPos ( start , end - start , Diagnostics . A_default_clause_cannot_appear_more_than_once_in_a_switch_statement ) ; } } } } function checkTaggedTemplateExpression ( node ) { if ( languageVersion < ScriptTarget . ES6 ) { return grammarErrorOnFirstToken ( node . template , Diagnostics . Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher ) ; } } function checkThrowStatement ( node ) { if ( node . expression === undefined ) { return grammarErrorAfterFirstToken ( node , Diagnostics . Line_break_not_permitted_here ) ; } } function checkTupleType ( node ) { return checkForDisallowedTrailingComma ( node . elementTypes ) || checkForAtLeastOneType ( node ) ; } function checkForAtLeastOneType ( node ) { if ( node . elementTypes . length === 0 ) { return grammarErrorOnNode ( node , Diagnostics . A_tuple_type_element_list_cannot_be_empty ) ; } } function checkTypeParameter ( node ) { if ( node . expression ) { return grammarErrorOnFirstToken ( node . expression , Diagnostics . Type_expected ) ; } } function checkTypeReference ( node ) { return checkTypeArguments ( node . typeArguments ) ; } function checkVariableDeclaration ( node ) { if ( inAmbientContext && node . initializer ) { var equalsPos = node . type ? skipTrivia ( sourceText , node . type . end ) : skipTrivia ( sourceText , node . name . end ) ; return grammarErrorAtPos ( equalsPos , "=" . length , Diagnostics . Initializers_are_not_allowed_in_ambient_contexts ) ; } if ( ! inAmbientContext && ! node . initializer && isConst ( node ) ) { return grammarErrorOnNode ( node , Diagnostics . const_declarations_must_be_initialized ) ; } if ( node . parserContextFlags & ParserContextFlags . StrictMode && isEvalOrArgumentsIdentifier ( node . name ) ) { return reportInvalidUseInStrictMode ( node . name ) ; } } function checkVariableDeclarations ( declarations ) { if ( declarations ) { if ( checkForDisallowedTrailingComma ( declarations ) ) { return true ; } if ( ! declarations . length ) { return grammarErrorAtPos ( declarations . pos , declarations . end - declarations . pos , Diagnostics . Variable_declaration_list_cannot_be_empty ) ; } var decl = declarations [ 0 ] ; if ( languageVersion < ScriptTarget . ES6 ) { if ( isLet ( decl ) ) { return grammarErrorOnFirstToken ( decl , Diagnostics . let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher ) ; } else if ( isConst ( decl ) ) { return grammarErrorOnFirstToken ( decl , Diagnostics . const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher ) ; } } } } function checkVariableStatement ( node ) { return checkVariableDeclarations ( node . declarations ) || checkForDisallowedLetOrConstStatement ( node ) ; } function checkForDisallowedLetOrConstStatement ( node ) { if ( ! allowLetAndConstDeclarations ( node . parent ) ) { if ( isLet ( node ) ) { return grammarErrorOnNode ( node , Diagnostics . let_declarations_can_only_be_declared_inside_a_block ) ; } else if ( isConst ( node ) ) { return grammarErrorOnNode ( node , Diagnostics . const_declarations_can_only_be_declared_inside_a_block ) ; } } } function allowLetAndConstDeclarations ( parent ) { switch ( parent . kind ) { case SyntaxKind . IfStatement : case SyntaxKind . DoStatement : case SyntaxKind . WhileStatement : case SyntaxKind . WithStatement : case SyntaxKind . ForStatement : case SyntaxKind . ForInStatement : return false ; case SyntaxKind . LabeledStatement : return allowLetAndConstDeclarations ( parent . parent ) ; } return true ; } function checkWithStatement ( node ) { if ( node . parserContextFlags & ParserContextFlags . StrictMode ) { return grammarErrorOnFirstToken ( node , Diagnostics . with_statements_are_not_allowed_in_strict_mode ) ; } } function checkYieldExpression ( node ) { if ( ! ( node . parserContextFlags & ParserContextFlags . Yield ) ) { return grammarErrorOnFirstToken ( node , Diagnostics . yield_expression_must_be_contained_within_a_generator_declaration ) ; } return grammarErrorOnFirstToken ( node , Diagnostics . yield_expressions_are_not_currently_supported ) ; } } export function createProgram ( rootNames , options , host ) { var program ; var files = [ ] ; var filesByName = { } ; var errors = [ ] ; var seenNoDefaultLib = options . noLib ; var commonSourceDirectory ; forEach ( rootNames , name => processRootFile ( name , false ) ) ; if ( ! seenNoDefaultLib ) { processRootFile ( host . getDefaultLibFilename ( options ) , true ) ; } verifyCompilerOptions ( ) ; errors . sort ( compareDiagnostics ) ; program = { getSourceFile : getSourceFile , getSourceFiles : ( ) => files , getCompilerOptions : ( ) => options , getCompilerHost : ( ) => host , getDiagnostics : getDiagnostics , getGlobalDiagnostics : getGlobalDiagnostics , getTypeChecker : fullTypeCheckMode => createTypeChecker ( program , fullTypeCheckMode ) , getCommonSourceDirectory : ( ) => commonSourceDirectory , } ; return program ; function getSourceFile ( filename ) { filename = host . getCanonicalFileName ( filename ) ; return hasProperty ( filesByName , filename ) ? filesByName [ filename ] : undefined ; } function getDiagnostics ( sourceFile ? ) { return sourceFile ? filter ( errors , e => e . file === sourceFile ) : errors ; } function getGlobalDiagnostics ( ) { return filter ( errors , e => ! e . file ) ; } function hasExtension ( filename ) { return getBaseFilename ( filename ) . indexOf ( "." ) >= 0 ; } function processRootFile ( filename , isDefaultLib ) { processSourceFile ( normalizePath ( filename ) , isDefaultLib ) ; } function processSourceFile ( filename , isDefaultLib , refFile ? , refPos ? , refEnd ? ) { if ( refEnd !== undefined && refPos !== undefined ) { var start = refPos ; var length = refEnd - refPos ; } var diagnostic ; if ( hasExtension ( filename ) ) { if ( ! options . allowNonTsExtensions && ! fileExtensionIs ( filename , ".ts" ) ) { diagnostic = Diagnostics . File_0_must_have_extension_ts_or_d_ts ; } else if ( ! findSourceFile ( filename , isDefaultLib , refFile , refPos , refEnd ) ) { diagnostic = Diagnostics . File_0_not_found ; } else if ( refFile && host . getCanonicalFileName ( filename ) === host . getCanonicalFileName ( refFile . filename ) ) { diagnostic = Diagnostics . A_file_cannot_have_a_reference_to_itself ; } } else { if ( options . allowNonTsExtensions && ! findSourceFile ( filename , isDefaultLib , refFile , refPos , refEnd ) ) { diagnostic = Diagnostics . File_0_not_found ; } else if ( ! findSourceFile ( filename + ".ts" , isDefaultLib , refFile , refPos , refEnd ) && ! findSourceFile ( filename + ".d.ts" , isDefaultLib , refFile , refPos , refEnd ) ) { diagnostic = Diagnostics . File_0_not_found ; filename += ".ts" ; } } if ( diagnostic ) { if ( refFile ) { errors . push ( createFileDiagnostic ( refFile , start , length , diagnostic , filename ) ) ; } else { errors . push ( createCompilerDiagnostic ( diagnostic , filename ) ) ; } } } function findSourceFile ( filename , isDefaultLib , refFile ? , refStart ? , refLength ? ) { var canonicalName = host . getCanonicalFileName ( filename ) ; if ( hasProperty ( filesByName , canonicalName ) ) { return getSourceFileFromCache ( filename , canonicalName , false ) ; } else { var normalizedAbsolutePath = getNormalizedAbsolutePath ( filename , host . getCurrentDirectory ( ) ) ; var canonicalAbsolutePath = host . getCanonicalFileName ( normalizedAbsolutePath ) ; if ( hasProperty ( filesByName , canonicalAbsolutePath ) ) { return getSourceFileFromCache ( normalizedAbsolutePath , canonicalAbsolutePath , true ) ; } var file = filesByName [ canonicalName ] = host . getSourceFile ( filename , options . target , hostErrorMessage => { errors . push ( createFileDiagnostic ( refFile , refStart , refLength , Diagnostics . Cannot_read_file_0_Colon_1 , filename , hostErrorMessage ) ) ; } ) ; if ( file ) { seenNoDefaultLib = seenNoDefaultLib || file . hasNoDefaultLib ; filesByName [ canonicalAbsolutePath ] = file ; if ( ! options . noResolve ) { var basePath = getDirectoryPath ( filename ) ; processReferencedFiles ( file , basePath ) ; processImportedModules ( file , basePath ) ; } if ( isDefaultLib ) { files . unshift ( file ) ; } else { files . push ( file ) ; } forEach ( file . getSyntacticDiagnostics ( ) , e => { errors . push ( e ) ; } ) ; } } return file ; function getSourceFileFromCache ( filename , canonicalName , useAbsolutePath ) { var file = filesByName [ canonicalName ] ; if ( file && host . useCaseSensitiveFileNames ( ) ) { var sourceFileName = useAbsolutePath ? getNormalizedAbsolutePath ( file . filename , host . getCurrentDirectory ( ) ) : file . filename ; if ( canonicalName !== sourceFileName ) { errors . push ( createFileDiagnostic ( refFile , refStart , refLength , Diagnostics . Filename_0_differs_from_already_included_filename_1_only_in_casing , filename , sourceFileName ) ) ; } } return file ; } } function processReferencedFiles ( file , basePath ) { forEach ( file . referencedFiles , ref => { var referencedFilename = isRootedDiskPath ( ref . filename ) ? ref . filename : combinePaths ( basePath , ref . filename ) ; processSourceFile ( normalizePath ( referencedFilename ) , false , file , ref . pos , ref . end ) ; } ) ; } function processImportedModules ( file , basePath ) { forEach ( file . statements , node => { if ( isExternalModuleImportDeclaration ( node ) && getExternalModuleImportDeclarationExpression ( node ) . kind === SyntaxKind . StringLiteral ) { var nameLiteral = < LiteralExpression > getExternalModuleImportDeclarationExpression ( node ) ; var moduleName = nameLiteral . text ; if ( moduleName ) { var searchPath = basePath ; while ( true ) { var searchName = normalizePath ( combinePaths ( searchPath , moduleName ) ) ; if ( findModuleSourceFile ( searchName + ".ts" , nameLiteral ) || findModuleSourceFile ( searchName + ".d.ts" , nameLiteral ) ) { break ; } var parentPath = getDirectoryPath ( searchPath ) ; if ( parentPath === searchPath ) { break ; } searchPath = parentPath ; } } } else if ( node . kind === SyntaxKind . ModuleDeclaration && ( < ModuleDeclaration > node ) . name . kind === SyntaxKind . StringLiteral && ( node . flags & NodeFlags . Ambient || isDeclarationFile ( file ) ) ) { forEachChild ( ( < ModuleDeclaration > node ) . body , node => { if ( isExternalModuleImportDeclaration ( node ) && getExternalModuleImportDeclarationExpression ( node ) . kind === SyntaxKind . StringLiteral ) { var nameLiteral = < LiteralExpression > getExternalModuleImportDeclarationExpression ( node ) ; var moduleName = nameLiteral . text ; if ( moduleName ) { var searchName = normalizePath ( combinePaths ( basePath , moduleName ) ) ; var tsFile = findModuleSourceFile ( searchName + ".ts" , nameLiteral ) ; if ( ! tsFile ) { findModuleSourceFile ( searchName + ".d.ts" , nameLiteral ) ; } } } } ) ; } } ) ; function findModuleSourceFile ( filename , nameLiteral ) { return findSourceFile ( filename , false , file , nameLiteral . pos , nameLiteral . end - nameLiteral . pos ) ; } } function verifyCompilerOptions ( ) { if ( ! options . sourceMap && ( options . mapRoot || options . sourceRoot ) ) { if ( options . mapRoot ) { errors . push ( createCompilerDiagnostic ( Diagnostics . Option_mapRoot_cannot_be_specified_without_specifying_sourcemap_option ) ) ; } if ( options . sourceRoot ) { errors . push ( createCompilerDiagnostic ( Diagnostics . Option_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option ) ) ; } return ; } var firstExternalModule = forEach ( files , f => isExternalModule ( f ) ? f : undefined ) ; if ( firstExternalModule && options . module === ModuleKind . None ) { var externalModuleErrorSpan = getErrorSpanForNode ( firstExternalModule . externalModuleIndicator ) ; var errorStart = skipTrivia ( firstExternalModule . text , externalModuleErrorSpan . pos ) ; var errorLength = externalModuleErrorSpan . end - errorStart ; errors . push ( createFileDiagnostic ( firstExternalModule , errorStart , errorLength , Diagnostics . Cannot_compile_external_modules_unless_the_module_flag_is_provided ) ) ; } if ( options . outDir || options . sourceRoot || ( options . mapRoot && ( ! options . out || firstExternalModule !== undefined ) ) ) { var commonPathComponents ; forEach ( files , sourceFile => { if ( ! ( sourceFile . flags & NodeFlags . DeclarationFile ) && ! fileExtensionIs ( sourceFile . filename , ".js" ) ) { var sourcePathComponents = getNormalizedPathComponents ( sourceFile . filename , host . getCurrentDirectory ( ) ) ; sourcePathComponents . pop ( ) ; if ( commonPathComponents ) { for ( var i = 0 ; i < Math . min ( commonPathComponents . length , sourcePathComponents . length ) ; i ++ ) { if ( commonPathComponents [ i ] !== sourcePathComponents [ i ] ) { if ( i === 0 ) { errors . push ( createCompilerDiagnostic ( Diagnostics . Cannot_find_the_common_subdirectory_path_for_the_input_files ) ) ; return ; } commonPathComponents . length = i ; break ; } } if ( sourcePathComponents . length < commonPathComponents . length ) { commonPathComponents . length = sourcePathComponents . length ; } } else { commonPathComponents = sourcePathComponents ; } } } ) ; commonSourceDirectory = getNormalizedPathFromPathComponents ( commonPathComponents ) ; if ( commonSourceDirectory ) { commonSourceDirectory += directorySeparator ; } } } } }