declare var global ; module ts { interface EmitTextWriter { write ( s ) : void ; writeTextOfNode ( sourceFile , node ) : void ; writeLine ( ) : void ; increaseIndent ( ) : void ; decreaseIndent ( ) : void ; getText ( ) : string ; rawWrite ( s ) : void ; writeLiteral ( s ) : void ; getTextPos ( ) : number ; getLine ( ) : number ; getColumn ( ) : number ; getIndent ( ) : number ; } interface SymbolAccessibilityDiagnostic { errorNode : Node ; diagnosticMessage : DiagnosticMessage ; typeName ? : DeclarationName ; } type GetSymbolAccessibilityDiagnostic = ( symbolAccesibilityResult : SymbolAccessiblityResult ) => SymbolAccessibilityDiagnostic ; interface EmitTextWriterWithSymbolWriter extends EmitTextWriter , SymbolWriter { getSymbolAccessibilityDiagnostic : GetSymbolAccessibilityDiagnostic ; } interface AliasDeclarationEmitInfo { declaration : ImportDeclaration ; outputPos : number ; indent : number ; asynchronousOutput ? : string ; } interface DeclarationEmit { reportedDeclarationError : boolean ; aliasDeclarationEmitInfo : AliasDeclarationEmitInfo [ ] ; synchronousDeclarationOutput : string ; referencePathsOutput : string ; } var indentStrings = [ "" , "    " ] ; export function getIndentString ( level ) { if ( indentStrings [ level ] === undefined ) { indentStrings [ level ] = getIndentString ( level - 1 ) + indentStrings [ 1 ] ; } return indentStrings [ level ] ; } function getIndentSize ( ) { return indentStrings [ 1 ] . length ; } export function shouldEmitToOwnFile ( sourceFile , compilerOptions ) { if ( ! isDeclarationFile ( sourceFile ) ) { if ( ( isExternalModule ( sourceFile ) || ! compilerOptions . out ) && ! fileExtensionIs ( sourceFile . filename , ".js" ) ) { return true ; } return false ; } return false ; } export function isExternalModuleOrDeclarationFile ( sourceFile ) { return isExternalModule ( sourceFile ) || isDeclarationFile ( sourceFile ) ; } function createTextWriter ( newLine ) { var output = "" ; var indent = 0 ; var lineStart = true ; var lineCount = 0 ; var linePos = 0 ; function write ( s ) { if ( s && s . length ) { if ( lineStart ) { output += getIndentString ( indent ) ; lineStart = false ; } output += s ; } } function rawWrite ( s ) { if ( s !== undefined ) { if ( lineStart ) { lineStart = false ; } output += s ; } } function writeLiteral ( s ) { if ( s && s . length ) { write ( s ) ; var lineStartsOfS = computeLineStarts ( s ) ; if ( lineStartsOfS . length > 1 ) { lineCount = lineCount + lineStartsOfS . length - 1 ; linePos = output . length - s . length + lineStartsOfS [ lineStartsOfS . length - 1 ] ; } } } function writeLine ( ) { if ( ! lineStart ) { output += newLine ; lineCount ++ ; linePos = output . length ; lineStart = true ; } } function writeTextOfNode ( sourceFile , node ) { write ( getSourceTextOfNodeFromSourceFile ( sourceFile , node ) ) ; } return { write , rawWrite , writeTextOfNode , writeLiteral , writeLine , increaseIndent : ( ) => indent ++ , decreaseIndent : ( ) => indent -- , getIndent : ( ) => indent , getTextPos : ( ) => output . length , getLine : ( ) => lineCount + 1 , getColumn : ( ) => lineStart ? indent * getIndentSize ( ) + 1 : output . length - linePos + 1 , getText : ( ) => output , } ; } function getLineOfLocalPosition ( currentSourceFile , pos ) { return currentSourceFile . getLineAndCharacterFromPosition ( pos ) . line ; } function emitNewLineBeforeLeadingComments ( currentSourceFile , writer , node , leadingComments ) { if ( leadingComments && leadingComments . length && node . pos !== leadingComments [ 0 ] . pos && getLineOfLocalPosition ( currentSourceFile , node . pos ) !== getLineOfLocalPosition ( currentSourceFile , leadingComments [ 0 ] . pos ) ) { writer . writeLine ( ) ; } } function emitComments ( currentSourceFile , writer , comments , trailingSeparator , newLine , writeComment ) { var emitLeadingSpace = ! trailingSeparator ; forEach ( comments , comment => { if ( emitLeadingSpace ) { writer . write ( " " ) ; emitLeadingSpace = false ; } writeComment ( currentSourceFile , writer , comment , newLine ) ; if ( comment . hasTrailingNewLine ) { writer . writeLine ( ) ; } else if ( trailingSeparator ) { writer . write ( " " ) ; } else { emitLeadingSpace = true ; } } ) ; } function writeCommentRange ( currentSourceFile , writer , comment , newLine ) { if ( currentSourceFile . text . charCodeAt ( comment . pos + 1 ) === CharacterCodes . asterisk ) { var firstCommentLineAndCharacter = currentSourceFile . getLineAndCharacterFromPosition ( comment . pos ) ; var firstCommentLineIndent ; for ( var pos = comment . pos , currentLine = firstCommentLineAndCharacter . line ; pos < comment . end ; currentLine ++ ) { var nextLineStart = currentSourceFile . getPositionFromLineAndCharacter ( currentLine + 1 , 1 ) ; if ( pos !== comment . pos ) { if ( firstCommentLineIndent === undefined ) { firstCommentLineIndent = calculateIndent ( currentSourceFile . getPositionFromLineAndCharacter ( firstCommentLineAndCharacter . line , 1 ) , comment . pos ) ; } var currentWriterIndentSpacing = writer . getIndent ( ) * getIndentSize ( ) ; var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent ( pos , nextLineStart ) ; if ( spacesToEmit > 0 ) { var numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize ( ) ; var indentSizeSpaceString = getIndentString ( ( spacesToEmit - numberOfSingleSpacesToEmit ) / getIndentSize ( ) ) ; writer . rawWrite ( indentSizeSpaceString ) ; while ( numberOfSingleSpacesToEmit ) { writer . rawWrite ( " " ) ; numberOfSingleSpacesToEmit -- ; } } else { writer . rawWrite ( "" ) ; } } writeTrimmedCurrentLine ( pos , nextLineStart ) ; pos = nextLineStart ; } } else { writer . write ( currentSourceFile . text . substring ( comment . pos , comment . end ) ) ; } function writeTrimmedCurrentLine ( pos , nextLineStart ) { var end = Math . min ( comment . end , nextLineStart - 1 ) ; var currentLineText = currentSourceFile . text . substring ( pos , end ) . replace ( /^\s+|\s+$/g , '' ) ; if ( currentLineText ) { writer . write ( currentLineText ) ; if ( end !== comment . end ) { writer . writeLine ( ) ; } } else { writer . writeLiteral ( newLine ) ; } } function calculateIndent ( pos , end ) { var currentLineIndent = 0 ; for ( ; pos < end && isWhiteSpace ( currentSourceFile . text . charCodeAt ( pos ) ) ; pos ++ ) { if ( currentSourceFile . text . charCodeAt ( pos ) === CharacterCodes . tab ) { currentLineIndent += getIndentSize ( ) - ( currentLineIndent % getIndentSize ( ) ) ; } else { currentLineIndent ++ ; } } return currentLineIndent ; } } function getFirstConstructorWithBody ( node ) { return forEach ( node . members , member => { if ( member . kind === SyntaxKind . Constructor && ( < ConstructorDeclaration > member ) . body ) { return < ConstructorDeclaration > member ; } } ) ; } function getAllAccessorDeclarations ( node , accessor ) { var firstAccessor ; var getAccessor ; var setAccessor ; if ( accessor . name . kind === SyntaxKind . ComputedPropertyName ) { firstAccessor = accessor ; if ( accessor . kind === SyntaxKind . GetAccessor ) { getAccessor = accessor ; } else if ( accessor . kind === SyntaxKind . SetAccessor ) { setAccessor = accessor ; } else { Debug . fail ( "Accessor has wrong kind" ) ; } } else { forEach ( node . members , ( member ) => { if ( ( member . kind === SyntaxKind . GetAccessor || member . kind === SyntaxKind . SetAccessor ) && ( < Identifier > member . name ) . text === ( < Identifier > accessor . name ) . text && ( member . flags & NodeFlags . Static ) === ( accessor . flags & NodeFlags . Static ) ) { if ( ! firstAccessor ) { firstAccessor = < AccessorDeclaration > member ; } if ( member . kind === SyntaxKind . GetAccessor && ! getAccessor ) { getAccessor = < AccessorDeclaration > member ; } if ( member . kind === SyntaxKind . SetAccessor && ! setAccessor ) { setAccessor = < AccessorDeclaration > member ; } } } ) ; } return { firstAccessor , getAccessor , setAccessor } ; } function getSourceFilePathInNewDir ( sourceFile , program , newDirPath ) { var compilerHost = program . getCompilerHost ( ) ; var sourceFilePath = getNormalizedAbsolutePath ( sourceFile . filename , compilerHost . getCurrentDirectory ( ) ) ; sourceFilePath = sourceFilePath . replace ( program . getCommonSourceDirectory ( ) , "" ) ; return combinePaths ( newDirPath , sourceFilePath ) ; } function getOwnEmitOutputFilePath ( sourceFile , program , extension ) { var compilerOptions = program . getCompilerOptions ( ) ; if ( compilerOptions . outDir ) { var emitOutputFilePathWithoutExtension = removeFileExtension ( getSourceFilePathInNewDir ( sourceFile , program , compilerOptions . outDir ) ) ; } else { var emitOutputFilePathWithoutExtension = removeFileExtension ( sourceFile . filename ) ; } return emitOutputFilePathWithoutExtension + extension ; } function writeFile ( compilerHost , diagnostics , filename , data , writeByteOrderMark ) { compilerHost . writeFile ( filename , data , writeByteOrderMark , hostErrorMessage => { diagnostics . push ( createCompilerDiagnostic ( Diagnostics . Could_not_write_file_0_Colon_1 , filename , hostErrorMessage ) ) ; } ) ; } function emitDeclarations ( program , resolver , diagnostics , jsFilePath , root ? ) { var newLine = program . getCompilerHost ( ) . getNewLine ( ) ; var compilerOptions = program . getCompilerOptions ( ) ; var compilerHost = program . getCompilerHost ( ) ; var write ; var writeLine ; var increaseIndent ; var decreaseIndent ; var writeTextOfNode ; var writer = createAndSetNewTextWriterWithSymbolWriter ( ) ; var enclosingDeclaration ; var currentSourceFile ; var reportedDeclarationError = false ; var emitJsDocComments = compilerOptions . removeComments ? function ( declaration ) { } : writeJsDocComments ; var aliasDeclarationEmitInfo = [ ] ; function createAndSetNewTextWriterWithSymbolWriter ( ) { var writer = < EmitTextWriterWithSymbolWriter > createTextWriter ( newLine ) ; writer . trackSymbol = trackSymbol ; writer . writeKeyword = writer . write ; writer . writeOperator = writer . write ; writer . writePunctuation = writer . write ; writer . writeSpace = writer . write ; writer . writeStringLiteral = writer . writeLiteral ; writer . writeParameter = writer . write ; writer . writeSymbol = writer . write ; setWriter ( writer ) ; return writer ; } function setWriter ( newWriter ) { writer = newWriter ; write = newWriter . write ; writeTextOfNode = newWriter . writeTextOfNode ; writeLine = newWriter . writeLine ; increaseIndent = newWriter . increaseIndent ; decreaseIndent = newWriter . decreaseIndent ; } function writeAsychronousImportDeclarations ( importDeclarations ) { var oldWriter = writer ; forEach ( importDeclarations , aliasToWrite => { var aliasEmitInfo = forEach ( aliasDeclarationEmitInfo , declEmitInfo => declEmitInfo . declaration === aliasToWrite ? declEmitInfo : undefined ) ; if ( aliasEmitInfo ) { createAndSetNewTextWriterWithSymbolWriter ( ) ; for ( var declarationIndent = aliasEmitInfo . indent ; declarationIndent ; declarationIndent -- ) { increaseIndent ( ) ; } writeImportDeclaration ( aliasToWrite ) ; aliasEmitInfo . asynchronousOutput = writer . getText ( ) ; } } ) ; setWriter ( oldWriter ) ; } function handleSymbolAccessibilityError ( symbolAccesibilityResult ) { if ( symbolAccesibilityResult . accessibility === SymbolAccessibility . Accessible ) { if ( symbolAccesibilityResult && symbolAccesibilityResult . aliasesToMakeVisible ) { writeAsychronousImportDeclarations ( symbolAccesibilityResult . aliasesToMakeVisible ) ; } } else { reportedDeclarationError = true ; var errorInfo = writer . getSymbolAccessibilityDiagnostic ( symbolAccesibilityResult ) ; if ( errorInfo ) { if ( errorInfo . typeName ) { diagnostics . push ( createDiagnosticForNode ( symbolAccesibilityResult . errorNode || errorInfo . errorNode , errorInfo . diagnosticMessage , getSourceTextOfNodeFromSourceFile ( currentSourceFile , errorInfo . typeName ) , symbolAccesibilityResult . errorSymbolName , symbolAccesibilityResult . errorModuleName ) ) ; } else { diagnostics . push ( createDiagnosticForNode ( symbolAccesibilityResult . errorNode || errorInfo . errorNode , errorInfo . diagnosticMessage , symbolAccesibilityResult . errorSymbolName , symbolAccesibilityResult . errorModuleName ) ) ; } } } } function trackSymbol ( symbol , enclosingDeclaration ? , meaning ? ) { handleSymbolAccessibilityError ( resolver . isSymbolAccessible ( symbol , enclosingDeclaration , meaning ) ) ; } function writeTypeOfDeclaration ( declaration , type , getSymbolAccessibilityDiagnostic ) { writer . getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic ; write ( ": " ) ; if ( type ) { emitType ( type ) ; } else { resolver . writeTypeOfDeclaration ( declaration , enclosingDeclaration , TypeFormatFlags . UseTypeOfFunction , writer ) ; } } function writeReturnTypeAtSignature ( signature , getSymbolAccessibilityDiagnostic ) { writer . getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic ; write ( ": " ) ; if ( signature . type ) { emitType ( signature . type ) ; } else { resolver . writeReturnTypeOfSignatureDeclaration ( signature , enclosingDeclaration , TypeFormatFlags . UseTypeOfFunction , writer ) ; } } function emitLines ( nodes ) { for ( var i = 0 , n = nodes . length ; i < n ; i ++ ) { emitNode ( nodes [ i ] ) ; } } function emitSeparatedList ( nodes , separator , eachNodeEmitFn ) { var currentWriterPos = writer . getTextPos ( ) ; for ( var i = 0 , n = nodes . length ; i < n ; i ++ ) { if ( currentWriterPos !== writer . getTextPos ( ) ) { write ( separator ) ; } currentWriterPos = writer . getTextPos ( ) ; eachNodeEmitFn ( nodes [ i ] ) ; } } function emitCommaList ( nodes , eachNodeEmitFn ) { emitSeparatedList ( nodes , ", " , eachNodeEmitFn ) ; } function writeJsDocComments ( declaration ) { if ( declaration ) { var jsDocComments = getJsDocComments ( declaration , currentSourceFile ) ; emitNewLineBeforeLeadingComments ( currentSourceFile , writer , declaration , jsDocComments ) ; emitComments ( currentSourceFile , writer , jsDocComments , true , newLine , writeCommentRange ) ; } } function emitTypeWithNewGetSymbolAccessibilityDiagnostic ( type , getSymbolAccessibilityDiagnostic ) { writer . getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic ; emitType ( type ) ; } function emitType ( type ) { switch ( type . kind ) { case SyntaxKind . AnyKeyword : case SyntaxKind . StringKeyword : case SyntaxKind . NumberKeyword : case SyntaxKind . BooleanKeyword : case SyntaxKind . VoidKeyword : case SyntaxKind . StringLiteral : return writeTextOfNode ( currentSourceFile , type ) ; case SyntaxKind . TypeReference : return emitTypeReference ( < TypeReferenceNode > type ) ; case SyntaxKind . TypeQuery : return emitTypeQuery ( < TypeQueryNode > type ) ; case SyntaxKind . ArrayType : return emitArrayType ( < ArrayTypeNode > type ) ; case SyntaxKind . TupleType : return emitTupleType ( < TupleTypeNode > type ) ; case SyntaxKind . UnionType : return emitUnionType ( < UnionTypeNode > type ) ; case SyntaxKind . ParenthesizedType : return emitParenType ( < ParenthesizedTypeNode > type ) ; case SyntaxKind . FunctionType : case SyntaxKind . ConstructorType : return emitSignatureDeclarationWithJsDocComments ( < FunctionOrConstructorTypeNode > type ) ; case SyntaxKind . TypeLiteral : return emitTypeLiteral ( < TypeLiteralNode > type ) ; case SyntaxKind . Identifier : return emitEntityName ( < Identifier > type ) ; case SyntaxKind . QualifiedName : return emitEntityName ( < QualifiedName > type ) ; default : Debug . fail ( "Unknown type annotation: " + type . kind ) ; } function emitEntityName ( entityName ) { var visibilityResult = resolver . isEntityNameVisible ( entityName , entityName . parent . kind === SyntaxKind . ImportDeclaration ? entityName . parent : enclosingDeclaration ) ; handleSymbolAccessibilityError ( visibilityResult ) ; writeEntityName ( entityName ) ; function writeEntityName ( entityName ) { if ( entityName . kind === SyntaxKind . Identifier ) { writeTextOfNode ( currentSourceFile , entityName ) ; } else { var qualifiedName = < QualifiedName > entityName ; writeEntityName ( qualifiedName . left ) ; write ( "." ) ; writeTextOfNode ( currentSourceFile , qualifiedName . right ) ; } } } function emitTypeReference ( type ) { emitEntityName ( type . typeName ) ; if ( type . typeArguments ) { write ( "<" ) ; emitCommaList ( type . typeArguments , emitType ) ; write ( ">" ) ; } } function emitTypeQuery ( type ) { write ( "typeof " ) ; emitEntityName ( type . exprName ) ; } function emitArrayType ( type ) { emitType ( type . elementType ) ; write ( "[]" ) ; } function emitTupleType ( type ) { write ( "[" ) ; emitCommaList ( type . elementTypes , emitType ) ; write ( "]" ) ; } function emitUnionType ( type ) { emitSeparatedList ( type . types , " | " , emitType ) ; } function emitParenType ( type ) { write ( "(" ) ; emitType ( type . type ) ; write ( ")" ) ; } function emitTypeLiteral ( type ) { write ( "{" ) ; if ( type . members . length ) { writeLine ( ) ; increaseIndent ( ) ; emitLines ( type . members ) ; decreaseIndent ( ) ; } write ( "}" ) ; } } function emitSourceFile ( node ) { currentSourceFile = node ; enclosingDeclaration = node ; emitLines ( node . statements ) ; } function emitExportAssignment ( node ) { write ( "export = " ) ; writeTextOfNode ( currentSourceFile , node . exportName ) ; write ( ";" ) ; writeLine ( ) ; } function emitModuleElementDeclarationFlags ( node ) { if ( node . parent === currentSourceFile ) { if ( node . flags & NodeFlags . Export ) { write ( "export " ) ; } if ( node . kind !== SyntaxKind . InterfaceDeclaration ) { write ( "declare " ) ; } } } function emitClassMemberDeclarationFlags ( node ) { if ( node . flags & NodeFlags . Private ) { write ( "private " ) ; } else if ( node . flags & NodeFlags . Protected ) { write ( "protected " ) ; } if ( node . flags & NodeFlags . Static ) { write ( "static " ) ; } } function emitImportDeclaration ( node ) { var nodeEmitInfo = { declaration : node , outputPos : writer . getTextPos ( ) , indent : writer . getIndent ( ) , hasWritten : resolver . isDeclarationVisible ( node ) } ; aliasDeclarationEmitInfo . push ( nodeEmitInfo ) ; if ( nodeEmitInfo . hasWritten ) { writeImportDeclaration ( node ) ; } } function writeImportDeclaration ( node ) { emitJsDocComments ( node ) ; if ( node . flags & NodeFlags . Export ) { write ( "export " ) ; } write ( "import " ) ; writeTextOfNode ( currentSourceFile , node . name ) ; write ( " = " ) ; if ( isInternalModuleImportDeclaration ( node ) ) { emitTypeWithNewGetSymbolAccessibilityDiagnostic ( < EntityName > node . moduleReference , getImportEntityNameVisibilityError ) ; write ( ";" ) ; } else { write ( "require(" ) ; writeTextOfNode ( currentSourceFile , getExternalModuleImportDeclarationExpression ( node ) ) ; write ( ");" ) ; } writer . writeLine ( ) ; function getImportEntityNameVisibilityError ( symbolAccesibilityResult ) { return { diagnosticMessage : Diagnostics . Import_declaration_0_is_using_private_name_1 , errorNode : node , typeName : node . name } ; } } function emitModuleDeclaration ( node ) { if ( resolver . isDeclarationVisible ( node ) ) { emitJsDocComments ( node ) ; emitModuleElementDeclarationFlags ( node ) ; write ( "module " ) ; writeTextOfNode ( currentSourceFile , node . name ) ; while ( node . body . kind !== SyntaxKind . ModuleBlock ) { node = < ModuleDeclaration > node . body ; write ( "." ) ; writeTextOfNode ( currentSourceFile , node . name ) ; } var prevEnclosingDeclaration = enclosingDeclaration ; enclosingDeclaration = node ; write ( " {" ) ; writeLine ( ) ; increaseIndent ( ) ; emitLines ( ( < ModuleBlock > node . body ) . statements ) ; decreaseIndent ( ) ; write ( "}" ) ; writeLine ( ) ; enclosingDeclaration = prevEnclosingDeclaration ; } } function emitTypeAliasDeclaration ( node ) { if ( resolver . isDeclarationVisible ( node ) ) { emitJsDocComments ( node ) ; emitModuleElementDeclarationFlags ( node ) ; write ( "type " ) ; writeTextOfNode ( currentSourceFile , node . name ) ; write ( " = " ) ; emitTypeWithNewGetSymbolAccessibilityDiagnostic ( node . type , getTypeAliasDeclarationVisibilityError ) ; write ( ";" ) ; writeLine ( ) ; } function getTypeAliasDeclarationVisibilityError ( symbolAccesibilityResult ) { return { diagnosticMessage : Diagnostics . Exported_type_alias_0_has_or_is_using_private_name_1 , errorNode : node . type , typeName : node . name } ; } } function emitEnumDeclaration ( node ) { if ( resolver . isDeclarationVisible ( node ) ) { emitJsDocComments ( node ) ; emitModuleElementDeclarationFlags ( node ) ; if ( isConst ( node ) ) { write ( "const " ) ; } write ( "enum " ) ; writeTextOfNode ( currentSourceFile , node . name ) ; write ( " {" ) ; writeLine ( ) ; increaseIndent ( ) ; emitLines ( node . members ) ; decreaseIndent ( ) ; write ( "}" ) ; writeLine ( ) ; } } function emitEnumMemberDeclaration ( node ) { emitJsDocComments ( node ) ; writeTextOfNode ( currentSourceFile , node . name ) ; var enumMemberValue = resolver . getEnumMemberValue ( node ) ; if ( enumMemberValue !== undefined ) { write ( " = " ) ; write ( enumMemberValue . toString ( ) ) ; } write ( "," ) ; writeLine ( ) ; } function emitTypeParameters ( typeParameters ) { function emitTypeParameter ( node ) { increaseIndent ( ) ; emitJsDocComments ( node ) ; decreaseIndent ( ) ; writeTextOfNode ( currentSourceFile , node . name ) ; if ( node . constraint && ( node . parent . kind !== SyntaxKind . Method || ! ( node . parent . flags & NodeFlags . Private ) ) ) { write ( " extends " ) ; if ( node . parent . kind === SyntaxKind . FunctionType || node . parent . kind === SyntaxKind . ConstructorType || ( node . parent . parent && node . parent . parent . kind === SyntaxKind . TypeLiteral ) ) { Debug . assert ( node . parent . kind === SyntaxKind . Method || node . parent . kind === SyntaxKind . FunctionType || node . parent . kind === SyntaxKind . ConstructorType || node . parent . kind === SyntaxKind . CallSignature || node . parent . kind === SyntaxKind . ConstructSignature ) ; emitType ( node . constraint ) ; } else { emitTypeWithNewGetSymbolAccessibilityDiagnostic ( node . constraint , getTypeParameterConstraintVisibilityError ) ; } } function getTypeParameterConstraintVisibilityError ( symbolAccesibilityResult ) { var diagnosticMessage ; switch ( node . parent . kind ) { case SyntaxKind . ClassDeclaration : diagnosticMessage = Diagnostics . Type_parameter_0_of_exported_class_has_or_is_using_private_name_1 ; break ; case SyntaxKind . InterfaceDeclaration : diagnosticMessage = Diagnostics . Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1 ; break ; case SyntaxKind . ConstructSignature : diagnosticMessage = Diagnostics . Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1 ; break ; case SyntaxKind . CallSignature : diagnosticMessage = Diagnostics . Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1 ; break ; case SyntaxKind . Method : if ( node . parent . flags & NodeFlags . Static ) { diagnosticMessage = Diagnostics . Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1 ; } else if ( node . parent . parent . kind === SyntaxKind . ClassDeclaration ) { diagnosticMessage = Diagnostics . Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1 ; } else { diagnosticMessage = Diagnostics . Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1 ; } break ; case SyntaxKind . FunctionDeclaration : diagnosticMessage = Diagnostics . Type_parameter_0_of_exported_function_has_or_is_using_private_name_1 ; break ; default : Debug . fail ( "This is unknown parent for type parameter: " + node . parent . kind ) ; } return { diagnosticMessage , errorNode : node , typeName : node . name } ; } } if ( typeParameters ) { write ( "<" ) ; emitCommaList ( typeParameters , emitTypeParameter ) ; write ( ">" ) ; } } function emitHeritageClause ( typeReferences , isImplementsList ) { if ( typeReferences ) { write ( isImplementsList ? " implements " : " extends " ) ; emitCommaList ( typeReferences , emitTypeOfTypeReference ) ; } function emitTypeOfTypeReference ( node ) { emitTypeWithNewGetSymbolAccessibilityDiagnostic ( node , getHeritageClauseVisibilityError ) ; function getHeritageClauseVisibilityError ( symbolAccesibilityResult ) { var diagnosticMessage ; if ( node . parent . parent . kind === SyntaxKind . ClassDeclaration ) { diagnosticMessage = isImplementsList ? Diagnostics . Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 : Diagnostics . Extends_clause_of_exported_class_0_has_or_is_using_private_name_1 ; } else { diagnosticMessage = Diagnostics . Extends_clause_of_exported_interface_0_has_or_is_using_private_name_1 ; } return { diagnosticMessage , errorNode : node , typeName : ( < Declaration > node . parent . parent ) . name } ; } } } function emitClassDeclaration ( node ) { function emitParameterProperties ( constructorDeclaration ) { if ( constructorDeclaration ) { forEach ( constructorDeclaration . parameters , param => { if ( param . flags & NodeFlags . AccessibilityModifier ) { emitPropertyDeclaration ( param ) ; } } ) ; } } if ( resolver . isDeclarationVisible ( node ) ) { emitJsDocComments ( node ) ; emitModuleElementDeclarationFlags ( node ) ; write ( "class " ) ; writeTextOfNode ( currentSourceFile , node . name ) ; var prevEnclosingDeclaration = enclosingDeclaration ; enclosingDeclaration = node ; emitTypeParameters ( node . typeParameters ) ; var baseTypeNode = getClassBaseTypeNode ( node ) ; if ( baseTypeNode ) { emitHeritageClause ( [ baseTypeNode ] , false ) ; } emitHeritageClause ( getClassImplementedTypeNodes ( node ) , true ) ; write ( " {" ) ; writeLine ( ) ; increaseIndent ( ) ; emitParameterProperties ( getFirstConstructorWithBody ( node ) ) ; emitLines ( node . members ) ; decreaseIndent ( ) ; write ( "}" ) ; writeLine ( ) ; enclosingDeclaration = prevEnclosingDeclaration ; } } function emitInterfaceDeclaration ( node ) { if ( resolver . isDeclarationVisible ( node ) ) { emitJsDocComments ( node ) ; emitModuleElementDeclarationFlags ( node ) ; write ( "interface " ) ; writeTextOfNode ( currentSourceFile , node . name ) ; var prevEnclosingDeclaration = enclosingDeclaration ; enclosingDeclaration = node ; emitTypeParameters ( node . typeParameters ) ; emitHeritageClause ( getInterfaceBaseTypeNodes ( node ) , false ) ; write ( " {" ) ; writeLine ( ) ; increaseIndent ( ) ; emitLines ( node . members ) ; decreaseIndent ( ) ; write ( "}" ) ; writeLine ( ) ; enclosingDeclaration = prevEnclosingDeclaration ; } } function emitPropertyDeclaration ( node ) { var name ; if ( global . ignoreDollar && node . name && ( name = node . name [ 'text' ] ) && name . indexOf ( '$' ) == 0 ) return ; emitJsDocComments ( node ) ; emitClassMemberDeclarationFlags ( node ) ; emitVariableDeclaration ( < VariableDeclaration > node ) ; write ( ";" ) ; writeLine ( ) ; } function emitVariableDeclaration ( node ) { if ( node . kind !== SyntaxKind . VariableDeclaration || resolver . isDeclarationVisible ( node ) ) { writeTextOfNode ( currentSourceFile , node . name ) ; if ( node . kind === SyntaxKind . Property && hasQuestionToken ( node ) ) { write ( "?" ) ; } if ( node . kind === SyntaxKind . Property && node . parent . kind === SyntaxKind . TypeLiteral ) { emitTypeOfVariableDeclarationFromTypeLiteral ( node ) ; } else if ( ! ( node . flags & NodeFlags . Private ) ) { writeTypeOfDeclaration ( node , node . type , getVariableDeclarationTypeVisibilityError ) ; } } function getVariableDeclarationTypeVisibilityError ( symbolAccesibilityResult ) { var diagnosticMessage ; if ( node . kind === SyntaxKind . VariableDeclaration ) { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ? Diagnostics . Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics . Exported_variable_0_has_or_is_using_name_1_from_private_module_2 : Diagnostics . Exported_variable_0_has_or_is_using_private_name_1 ; } else if ( node . kind === SyntaxKind . Property ) { if ( node . flags & NodeFlags . Static ) { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ? Diagnostics . Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics . Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics . Public_static_property_0_of_exported_class_has_or_is_using_private_name_1 ; } else if ( node . parent . kind === SyntaxKind . ClassDeclaration ) { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ? Diagnostics . Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics . Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics . Public_property_0_of_exported_class_has_or_is_using_private_name_1 ; } else { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? Diagnostics . Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics . Property_0_of_exported_interface_has_or_is_using_private_name_1 ; } } return diagnosticMessage !== undefined ? { diagnosticMessage , errorNode : node , typeName : node . name } : undefined ; } } function emitTypeOfVariableDeclarationFromTypeLiteral ( node ) { if ( node . type ) { write ( ": " ) ; emitType ( node . type ) ; } } function emitVariableStatement ( node ) { var hasDeclarationWithEmit = forEach ( node . declarations , varDeclaration => resolver . isDeclarationVisible ( varDeclaration ) ) ; if ( hasDeclarationWithEmit ) { emitJsDocComments ( node ) ; emitModuleElementDeclarationFlags ( node ) ; if ( isLet ( node ) ) { write ( "let " ) ; } else if ( isConst ( node ) ) { write ( "const " ) ; } else { write ( "var " ) ; } emitCommaList ( node . declarations , emitVariableDeclaration ) ; write ( ";" ) ; writeLine ( ) ; } } function emitAccessorDeclaration ( node ) { var accessors = getAllAccessorDeclarations ( < ClassDeclaration > node . parent , node ) ; if ( node === accessors . firstAccessor && resolver . isDeclarationVisible ( node ) ) { var name ; if ( global . ignoreDollar && node . name && ( name = node . name [ 'text' ] ) && name . indexOf ( '$' ) == 0 ) return ; emitJsDocComments ( accessors . getAccessor ) ; emitJsDocComments ( accessors . setAccessor ) ; emitClassMemberDeclarationFlags ( node ) ; writeTextOfNode ( currentSourceFile , node . name ) ; if ( ! ( node . flags & NodeFlags . Private ) ) { var accessorWithTypeAnnotation = node ; var type = getTypeAnnotationFromAccessor ( node ) ; if ( ! type ) { var anotherAccessor = node . kind === SyntaxKind . GetAccessor ? accessors . setAccessor : accessors . getAccessor ; type = getTypeAnnotationFromAccessor ( anotherAccessor ) ; if ( type ) { accessorWithTypeAnnotation = anotherAccessor ; } } writeTypeOfDeclaration ( node , type , getAccessorDeclarationTypeVisibilityError ) ; } write ( ";" ) ; writeLine ( ) ; } function getTypeAnnotationFromAccessor ( accessor ) { if ( accessor ) { return accessor . kind === SyntaxKind . GetAccessor ? accessor . type : accessor . parameters [ 0 ] . type ; } } function getAccessorDeclarationTypeVisibilityError ( symbolAccesibilityResult ) { var diagnosticMessage ; if ( accessorWithTypeAnnotation . kind === SyntaxKind . SetAccessor ) { if ( accessorWithTypeAnnotation . parent . flags & NodeFlags . Static ) { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? Diagnostics . Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics . Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1 ; } else { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? Diagnostics . Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics . Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_name_1 ; } return { diagnosticMessage , errorNode : < Node > accessorWithTypeAnnotation . parameters [ 0 ] , typeName : accessorWithTypeAnnotation . name } ; } else { if ( accessorWithTypeAnnotation . flags & NodeFlags . Static ) { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ? Diagnostics . Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : Diagnostics . Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1 : Diagnostics . Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_name_0 ; } else { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ? Diagnostics . Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : Diagnostics . Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1 : Diagnostics . Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_name_0 ; } return { diagnosticMessage , errorNode : < Node > accessorWithTypeAnnotation . name , typeName : undefined } ; } } } function emitFunctionDeclaration ( node ) { if ( ( node . kind !== SyntaxKind . FunctionDeclaration || resolver . isDeclarationVisible ( node ) ) && ! resolver . isImplementationOfOverload ( node ) ) { var name ; if ( global . ignoreDollar && node . name && ( name = node . name [ 'text' ] ) && name . indexOf ( '$' ) == 0 ) return ; emitJsDocComments ( node ) ; if ( node . kind === SyntaxKind . FunctionDeclaration ) { emitModuleElementDeclarationFlags ( node ) ; } else if ( node . kind === SyntaxKind . Method ) { emitClassMemberDeclarationFlags ( node ) ; } if ( node . kind === SyntaxKind . FunctionDeclaration ) { write ( "function " ) ; writeTextOfNode ( currentSourceFile , node . name ) ; } else if ( node . kind === SyntaxKind . Constructor ) { write ( "constructor" ) ; } else { writeTextOfNode ( currentSourceFile , node . name ) ; if ( hasQuestionToken ( node ) ) { write ( "?" ) ; } } emitSignatureDeclaration ( node ) ; } } function emitSignatureDeclarationWithJsDocComments ( node ) { emitJsDocComments ( node ) ; emitSignatureDeclaration ( node ) ; } function emitSignatureDeclaration ( node ) { if ( node . kind === SyntaxKind . ConstructSignature || node . kind === SyntaxKind . ConstructorType ) { write ( "new " ) ; } emitTypeParameters ( node . typeParameters ) ; if ( node . kind === SyntaxKind . IndexSignature ) { write ( "[" ) ; } else { write ( "(" ) ; } var prevEnclosingDeclaration = enclosingDeclaration ; enclosingDeclaration = node ; emitCommaList ( node . parameters , emitParameterDeclaration ) ; if ( node . kind === SyntaxKind . IndexSignature ) { write ( "]" ) ; } else { write ( ")" ) ; } var isFunctionTypeOrConstructorType = node . kind === SyntaxKind . FunctionType || node . kind === SyntaxKind . ConstructorType ; if ( isFunctionTypeOrConstructorType || node . parent . kind === SyntaxKind . TypeLiteral ) { if ( node . type ) { write ( isFunctionTypeOrConstructorType ? " => " : ": " ) ; emitType ( node . type ) ; } } else if ( node . kind !== SyntaxKind . Constructor && ! ( node . flags & NodeFlags . Private ) ) { writeReturnTypeAtSignature ( node , getReturnTypeVisibilityError ) ; } enclosingDeclaration = prevEnclosingDeclaration ; if ( ! isFunctionTypeOrConstructorType ) { write ( ";" ) ; writeLine ( ) ; } function getReturnTypeVisibilityError ( symbolAccesibilityResult ) { var diagnosticMessage ; switch ( node . kind ) { case SyntaxKind . ConstructSignature : diagnosticMessage = symbolAccesibilityResult . errorModuleName ? Diagnostics . Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : Diagnostics . Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0 ; break ; case SyntaxKind . CallSignature : diagnosticMessage = symbolAccesibilityResult . errorModuleName ? Diagnostics . Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : Diagnostics . Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0 ; break ; case SyntaxKind . IndexSignature : diagnosticMessage = symbolAccesibilityResult . errorModuleName ? Diagnostics . Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : Diagnostics . Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0 ; break ; case SyntaxKind . Method : if ( node . flags & NodeFlags . Static ) { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ? Diagnostics . Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : Diagnostics . Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 : Diagnostics . Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0 ; } else if ( node . parent . kind === SyntaxKind . ClassDeclaration ) { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ? Diagnostics . Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : Diagnostics . Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 : Diagnostics . Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0 ; } else { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? Diagnostics . Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : Diagnostics . Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0 ; } break ; case SyntaxKind . FunctionDeclaration : diagnosticMessage = symbolAccesibilityResult . errorModuleName ? symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ? Diagnostics . Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : Diagnostics . Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1 : Diagnostics . Return_type_of_exported_function_has_or_is_using_private_name_0 ; break ; default : Debug . fail ( "This is unknown kind for signature: " + node . kind ) ; } return { diagnosticMessage , errorNode : < Node > node . name || node , } ; } } function emitParameterDeclaration ( node ) { increaseIndent ( ) ; emitJsDocComments ( node ) ; if ( node . dotDotDotToken ) { write ( "..." ) ; } writeTextOfNode ( currentSourceFile , node . name ) ; if ( node . initializer || hasQuestionToken ( node ) ) { write ( "?" ) ; } decreaseIndent ( ) ; if ( node . parent . kind === SyntaxKind . FunctionType || node . parent . kind === SyntaxKind . ConstructorType || node . parent . parent . kind === SyntaxKind . TypeLiteral ) { emitTypeOfVariableDeclarationFromTypeLiteral ( node ) ; } else if ( ! ( node . parent . flags & NodeFlags . Private ) ) { writeTypeOfDeclaration ( node , node . type , getParameterDeclarationTypeVisibilityError ) ; } function getParameterDeclarationTypeVisibilityError ( symbolAccesibilityResult ) { var diagnosticMessage ; switch ( node . parent . kind ) { case SyntaxKind . Constructor : diagnosticMessage = symbolAccesibilityResult . errorModuleName ? symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ? Diagnostics . Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics . Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics . Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1 ; break ; case SyntaxKind . ConstructSignature : diagnosticMessage = symbolAccesibilityResult . errorModuleName ? Diagnostics . Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics . Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1 ; break ; case SyntaxKind . CallSignature : diagnosticMessage = symbolAccesibilityResult . errorModuleName ? Diagnostics . Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics . Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1 ; break ; case SyntaxKind . Method : if ( node . parent . flags & NodeFlags . Static ) { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ? Diagnostics . Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics . Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics . Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1 ; } else if ( node . parent . parent . kind === SyntaxKind . ClassDeclaration ) { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ? Diagnostics . Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics . Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics . Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1 ; } else { diagnosticMessage = symbolAccesibilityResult . errorModuleName ? Diagnostics . Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics . Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1 ; } break ; case SyntaxKind . FunctionDeclaration : diagnosticMessage = symbolAccesibilityResult . errorModuleName ? symbolAccesibilityResult . accessibility === SymbolAccessibility . CannotBeNamed ? Diagnostics . Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : Diagnostics . Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 : Diagnostics . Parameter_0_of_exported_function_has_or_is_using_private_name_1 ; break ; default : Debug . fail ( "This is unknown parent for parameter: " + node . parent . kind ) ; } return { diagnosticMessage , errorNode : node , typeName : node . name } ; } } function emitNode ( node ) { switch ( node . kind ) { case SyntaxKind . Constructor : case SyntaxKind . FunctionDeclaration : case SyntaxKind . Method : return emitFunctionDeclaration ( < FunctionLikeDeclaration > node ) ; case SyntaxKind . ConstructSignature : case SyntaxKind . CallSignature : case SyntaxKind . IndexSignature : return emitSignatureDeclarationWithJsDocComments ( < SignatureDeclaration > node ) ; case SyntaxKind . GetAccessor : case SyntaxKind . SetAccessor : return emitAccessorDeclaration ( < AccessorDeclaration > node ) ; case SyntaxKind . VariableStatement : return emitVariableStatement ( < VariableStatement > node ) ; case SyntaxKind . Property : return emitPropertyDeclaration ( < PropertyDeclaration > node ) ; case SyntaxKind . InterfaceDeclaration : return emitInterfaceDeclaration ( < InterfaceDeclaration > node ) ; case SyntaxKind . ClassDeclaration : return emitClassDeclaration ( < ClassDeclaration > node ) ; case SyntaxKind . TypeAliasDeclaration : return emitTypeAliasDeclaration ( < TypeAliasDeclaration > node ) ; case SyntaxKind . EnumMember : return emitEnumMemberDeclaration ( < EnumMember > node ) ; case SyntaxKind . EnumDeclaration : return emitEnumDeclaration ( < EnumDeclaration > node ) ; case SyntaxKind . ModuleDeclaration : return emitModuleDeclaration ( < ModuleDeclaration > node ) ; case SyntaxKind . ImportDeclaration : return emitImportDeclaration ( < ImportDeclaration > node ) ; case SyntaxKind . ExportAssignment : return emitExportAssignment ( < ExportAssignment > node ) ; case SyntaxKind . SourceFile : return emitSourceFile ( < SourceFile > node ) ; } } var referencePathsOutput = "" ; function writeReferencePath ( referencedFile ) { var declFileName = referencedFile . flags & NodeFlags . DeclarationFile ? referencedFile . filename : shouldEmitToOwnFile ( referencedFile , compilerOptions ) ? getOwnEmitOutputFilePath ( referencedFile , program , ".d.ts" ) : removeFileExtension ( compilerOptions . out ) + ".d.ts" ; declFileName = getRelativePathToDirectoryOrUrl ( getDirectoryPath ( normalizeSlashes ( jsFilePath ) ) , declFileName , compilerHost . getCurrentDirectory ( ) , compilerHost . getCanonicalFileName , false ) ; referencePathsOutput += "/// <reference path=\"" + declFileName + "\" />" + newLine ; } if ( root ) { if ( ! compilerOptions . noResolve ) { var addedGlobalFileReference = false ; forEach ( root . referencedFiles , fileReference => { var referencedFile = tryResolveScriptReference ( program , root , fileReference ) ; if ( referencedFile && ( ( referencedFile . flags & NodeFlags . DeclarationFile ) || shouldEmitToOwnFile ( referencedFile , compilerOptions ) || ! addedGlobalFileReference ) ) { writeReferencePath ( referencedFile ) ; if ( ! isExternalModuleOrDeclarationFile ( referencedFile ) ) { addedGlobalFileReference = true ; } } } ) ; } emitNode ( root ) ; } else { var emittedReferencedFiles = [ ] ; forEach ( program . getSourceFiles ( ) , sourceFile => { if ( ! isExternalModuleOrDeclarationFile ( sourceFile ) ) { if ( ! compilerOptions . noResolve ) { forEach ( sourceFile . referencedFiles , fileReference => { var referencedFile = tryResolveScriptReference ( program , sourceFile , fileReference ) ; if ( referencedFile && ( isExternalModuleOrDeclarationFile ( referencedFile ) && ! contains ( emittedReferencedFiles , referencedFile ) ) ) { writeReferencePath ( referencedFile ) ; emittedReferencedFiles . push ( referencedFile ) ; } } ) ; } emitNode ( sourceFile ) ; } } ) ; } return { reportedDeclarationError , aliasDeclarationEmitInfo , synchronousDeclarationOutput : writer . getText ( ) , referencePathsOutput , } ; } export function getDeclarationDiagnostics ( program , resolver , targetSourceFile ) { var diagnostics = [ ] ; var jsFilePath = getOwnEmitOutputFilePath ( targetSourceFile , program , ".js" ) ; emitDeclarations ( program , resolver , diagnostics , jsFilePath , targetSourceFile ) ; return diagnostics ; } export function emitFiles ( resolver , targetSourceFile ? ) { var program = resolver . getProgram ( ) ; var compilerHost = program . getCompilerHost ( ) ; var compilerOptions = program . getCompilerOptions ( ) ; var sourceMapDataList = compilerOptions . sourceMap ? [ ] : undefined ; var diagnostics = [ ] ; var newLine = program . getCompilerHost ( ) . getNewLine ( ) ; function emitJavaScript ( jsFilePath , root ? ) { var writer = createTextWriter ( newLine ) ; var write = writer . write ; var writeTextOfNode = writer . writeTextOfNode ; var writeLine = writer . writeLine ; var increaseIndent = writer . increaseIndent ; var decreaseIndent = writer . decreaseIndent ; var currentSourceFile ; var extendsEmitted = false ; var defineEmitted = false ; /** write emitted output to disk*/ var writeEmittedFiles = writeJavaScriptFile ; /** Emit leading comments of the node */ var emitLeadingComments = compilerOptions . removeComments ? ( node ) => { } : emitLeadingDeclarationComments ; /** Emit Trailing comments of the node */ var emitTrailingComments = compilerOptions . removeComments ? ( node ) => { } : emitTrailingDeclarationComments ; var emitLeadingCommentsOfPosition = compilerOptions . removeComments ? ( pos ) => { } : emitLeadingCommentsOfLocalPosition ; var detachedCommentsInfo ; /** Emit detached comments of the node */ var emitDetachedComments = compilerOptions . removeComments ? ( node ) => { } : emitDetachedCommentsAtPosition ; /** Emits /// or pinned which is comment starting with /*! comments */ var emitPinnedOrTripleSlashComments = compilerOptions . removeComments ? ( node ) => { } : emitPinnedOrTripleSlashCommentsOfNode ; var writeComment = writeCommentRange ; /** Emit a node */ var emit = emitNode ; /** Called just before starting emit of a node */ var emitStart = function ( node ) { } ; /** Called once the emit of the node is done */ var emitEnd = function ( node ) { } ; param tokenKind param startPos param emitFn var emitToken = emitTokenText ; param scopeDeclaration param scopeName var scopeEmitStart = function ( scopeDeclaration , scopeName ? ) { } ; /** Called after coming out of the scope */ var scopeEmitEnd = function ( ) { } ; /** Sourcemap data that will get encoded */ var sourceMapData ; function initializeEmitterWithSourceMaps ( ) { var sourceMapDir ; var sourceMapSourceIndex = - 1 ; var sourceMapNameIndexMap = { } ; var sourceMapNameIndices = [ ] ; function getSourceMapNameIndex ( ) { return sourceMapNameIndices . length ? sourceMapNameIndices [ sourceMapNameIndices . length - 1 ] : - 1 ; } var lastRecordedSourceMapSpan ; var lastEncodedSourceMapSpan = { emittedLine : 1 , emittedColumn : 1 , sourceLine : 1 , sourceColumn : 1 , sourceIndex : 0 } ; var lastEncodedNameIndex = 0 ; function encodeLastRecordedSourceMapSpan ( ) { if ( ! lastRecordedSourceMapSpan || lastRecordedSourceMapSpan === lastEncodedSourceMapSpan ) { return ; } var prevEncodedEmittedColumn = lastEncodedSourceMapSpan . emittedColumn ; if ( lastEncodedSourceMapSpan . emittedLine == lastRecordedSourceMapSpan . emittedLine ) { if ( sourceMapData . sourceMapMappings ) { sourceMapData . sourceMapMappings += "," ; } } else { for ( var encodedLine = lastEncodedSourceMapSpan . emittedLine ; encodedLine < lastRecordedSourceMapSpan . emittedLine ; encodedLine ++ ) { sourceMapData . sourceMapMappings += ";" ; } prevEncodedEmittedColumn = 1 ; } sourceMapData . sourceMapMappings += base64VLQFormatEncode ( lastRecordedSourceMapSpan . emittedColumn - prevEncodedEmittedColumn ) ; sourceMapData . sourceMapMappings += base64VLQFormatEncode ( lastRecordedSourceMapSpan . sourceIndex - lastEncodedSourceMapSpan . sourceIndex ) ; sourceMapData . sourceMapMappings += base64VLQFormatEncode ( lastRecordedSourceMapSpan . sourceLine - lastEncodedSourceMapSpan . sourceLine ) ; sourceMapData . sourceMapMappings += base64VLQFormatEncode ( lastRecordedSourceMapSpan . sourceColumn - lastEncodedSourceMapSpan . sourceColumn ) ; if ( lastRecordedSourceMapSpan . nameIndex >= 0 ) { sourceMapData . sourceMapMappings += base64VLQFormatEncode ( lastRecordedSourceMapSpan . nameIndex - lastEncodedNameIndex ) ; lastEncodedNameIndex = lastRecordedSourceMapSpan . nameIndex ; } lastEncodedSourceMapSpan = lastRecordedSourceMapSpan ; sourceMapData . sourceMapDecodedMappings . push ( lastEncodedSourceMapSpan ) ; function base64VLQFormatEncode ( inValue ) { function base64FormatEncode ( inValue ) { if ( inValue < 64 ) { return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' . charAt ( inValue ) ; } throw TypeError ( inValue + ": not a 64 based value" ) ; } if ( inValue < 0 ) { inValue = ( ( - inValue ) << 1 ) + 1 ; } else { inValue = inValue << 1 ; } var encodedStr = "" ; do { var currentDigit = inValue & 31 ; inValue = inValue >> 5 ; if ( inValue > 0 ) { currentDigit = currentDigit | 32 ; } encodedStr = encodedStr + base64FormatEncode ( currentDigit ) ; } while ( inValue > 0 ) ; return encodedStr ; } } function recordSourceMapSpan ( pos ) { var sourceLinePos = currentSourceFile . getLineAndCharacterFromPosition ( pos ) ; var emittedLine = writer . getLine ( ) ; var emittedColumn = writer . getColumn ( ) ; if ( ! lastRecordedSourceMapSpan || lastRecordedSourceMapSpan . emittedLine != emittedLine || lastRecordedSourceMapSpan . emittedColumn != emittedColumn || ( lastRecordedSourceMapSpan . sourceIndex === sourceMapSourceIndex && ( lastRecordedSourceMapSpan . sourceLine > sourceLinePos . line || ( lastRecordedSourceMapSpan . sourceLine === sourceLinePos . line && lastRecordedSourceMapSpan . sourceColumn > sourceLinePos . character ) ) ) ) { encodeLastRecordedSourceMapSpan ( ) ; lastRecordedSourceMapSpan = { emittedLine : emittedLine , emittedColumn : emittedColumn , sourceLine : sourceLinePos . line , sourceColumn : sourceLinePos . character , nameIndex : getSourceMapNameIndex ( ) , sourceIndex : sourceMapSourceIndex } ; } else { lastRecordedSourceMapSpan . sourceLine = sourceLinePos . line ; lastRecordedSourceMapSpan . sourceColumn = sourceLinePos . character ; lastRecordedSourceMapSpan . sourceIndex = sourceMapSourceIndex ; } } function recordEmitNodeStartSpan ( node ) { recordSourceMapSpan ( skipTrivia ( currentSourceFile . text , node . pos ) ) ; } function recordEmitNodeEndSpan ( node ) { recordSourceMapSpan ( node . end ) ; } function writeTextWithSpanRecord ( tokenKind , startPos , emitFn ? ) { var tokenStartPos = ts . skipTrivia ( currentSourceFile . text , startPos ) ; recordSourceMapSpan ( tokenStartPos ) ; var tokenEndPos = emitTokenText ( tokenKind , tokenStartPos , emitFn ) ; recordSourceMapSpan ( tokenEndPos ) ; return tokenEndPos ; } function recordNewSourceFileStart ( node ) { var sourcesDirectoryPath = compilerOptions . sourceRoot ? program . getCommonSourceDirectory ( ) : sourceMapDir ; sourceMapData . sourceMapSources . push ( getRelativePathToDirectoryOrUrl ( sourcesDirectoryPath , node . filename , compilerHost . getCurrentDirectory ( ) , compilerHost . getCanonicalFileName , true ) ) ; sourceMapSourceIndex = sourceMapData . sourceMapSources . length - 1 ; sourceMapData . inputSourceFileNames . push ( node . filename ) ; } function recordScopeNameOfNode ( node , scopeName ? ) { function recordScopeNameIndex ( scopeNameIndex ) { sourceMapNameIndices . push ( scopeNameIndex ) ; } function recordScopeNameStart ( scopeName ) { var scopeNameIndex = - 1 ; if ( scopeName ) { var parentIndex = getSourceMapNameIndex ( ) ; if ( parentIndex !== - 1 ) { scopeName = sourceMapData . sourceMapNames [ parentIndex ] + "." + scopeName ; } scopeNameIndex = getProperty ( sourceMapNameIndexMap , scopeName ) ; if ( scopeNameIndex === undefined ) { scopeNameIndex = sourceMapData . sourceMapNames . length ; sourceMapData . sourceMapNames . push ( scopeName ) ; sourceMapNameIndexMap [ scopeName ] = scopeNameIndex ; } } recordScopeNameIndex ( scopeNameIndex ) ; } if ( scopeName ) { recordScopeNameStart ( scopeName ) ; } else if ( node . kind === SyntaxKind . FunctionDeclaration || node . kind === SyntaxKind . FunctionExpression || node . kind === SyntaxKind . Method || node . kind === SyntaxKind . GetAccessor || node . kind === SyntaxKind . SetAccessor || node . kind === SyntaxKind . ModuleDeclaration || node . kind === SyntaxKind . ClassDeclaration || node . kind === SyntaxKind . EnumDeclaration ) { if ( ( < Declaration > node ) . name ) { scopeName = ( < Identifier > ( < Declaration > node ) . name ) . text ; } recordScopeNameStart ( scopeName ) ; } else { recordScopeNameIndex ( getSourceMapNameIndex ( ) ) ; } } function recordScopeNameEnd ( ) { sourceMapNameIndices . pop ( ) ; } ; function writeCommentRangeWithMap ( curentSourceFile , writer , comment , newLine ) { recordSourceMapSpan ( comment . pos ) ; writeCommentRange ( currentSourceFile , writer , comment , newLine ) ; recordSourceMapSpan ( comment . end ) ; } function serializeSourceMapContents ( version , file , sourceRoot , sources , names , mappings ) { if ( typeof JSON !== "undefined" ) { return JSON . stringify ( { version : version , file : file , sourceRoot : sourceRoot , sources : sources , names : names , mappings : mappings } ) ; } return "{\"version\":" + version + ",\"file\":\"" + escapeString ( file ) + "\",\"sourceRoot\":\"" + escapeString ( sourceRoot ) + "\",\"sources\":[" + serializeStringArray ( sources ) + "],\"names\":[" + serializeStringArray ( names ) + "],\"mappings\":\"" + escapeString ( mappings ) + "\"}" ; function serializeStringArray ( list ) { var output = "" ; for ( var i = 0 , n = list . length ; i < n ; i ++ ) { if ( i ) { output += "," ; } output += "\"" + escapeString ( list [ i ] ) + "\"" ; } return output ; } } function writeJavaScriptAndSourceMapFile ( emitOutput , writeByteOrderMark ) { encodeLastRecordedSourceMapSpan ( ) ; writeFile ( compilerHost , diagnostics , sourceMapData . sourceMapFilePath , serializeSourceMapContents ( 3 , sourceMapData . sourceMapFile , sourceMapData . sourceMapSourceRoot , sourceMapData . sourceMapSources , sourceMapData . sourceMapNames , sourceMapData . sourceMapMappings ) , false ) ; sourceMapDataList . push ( sourceMapData ) ; writeJavaScriptFile ( emitOutput + "//# sourceMappingURL=" + sourceMapData . jsSourceMappingURL , writeByteOrderMark ) ; } var sourceMapJsFile = getBaseFilename ( normalizeSlashes ( jsFilePath ) ) ; sourceMapData = { sourceMapFilePath : jsFilePath + ".map" , jsSourceMappingURL : sourceMapJsFile + ".map" , sourceMapFile : sourceMapJsFile , sourceMapSourceRoot : compilerOptions . sourceRoot || "" , sourceMapSources : [ ] , inputSourceFileNames : [ ] , sourceMapNames : [ ] , sourceMapMappings : "" , sourceMapDecodedMappings : [ ] } ; sourceMapData . sourceMapSourceRoot = ts . normalizeSlashes ( sourceMapData . sourceMapSourceRoot ) ; if ( sourceMapData . sourceMapSourceRoot . length && sourceMapData . sourceMapSourceRoot . charCodeAt ( sourceMapData . sourceMapSourceRoot . length - 1 ) !== CharacterCodes . slash ) { sourceMapData . sourceMapSourceRoot += directorySeparator ; } if ( compilerOptions . mapRoot ) { sourceMapDir = normalizeSlashes ( compilerOptions . mapRoot ) ; if ( root ) { sourceMapDir = getDirectoryPath ( getSourceFilePathInNewDir ( root , program , sourceMapDir ) ) ; } if ( ! isRootedDiskPath ( sourceMapDir ) && ! isUrl ( sourceMapDir ) ) { sourceMapDir = combinePaths ( program . getCommonSourceDirectory ( ) , sourceMapDir ) ; sourceMapData . jsSourceMappingURL = getRelativePathToDirectoryOrUrl ( getDirectoryPath ( normalizePath ( jsFilePath ) ) , combinePaths ( sourceMapDir , sourceMapData . jsSourceMappingURL ) , compilerHost . getCurrentDirectory ( ) , compilerHost . getCanonicalFileName , true ) ; } else { sourceMapData . jsSourceMappingURL = combinePaths ( sourceMapDir , sourceMapData . jsSourceMappingURL ) ; } } else { sourceMapDir = getDirectoryPath ( normalizePath ( jsFilePath ) ) ; } function emitNodeWithMap ( node ) { if ( node ) { if ( node . kind != SyntaxKind . SourceFile ) { recordEmitNodeStartSpan ( node ) ; emitNode ( node ) ; recordEmitNodeEndSpan ( node ) ; } else { recordNewSourceFileStart ( < SourceFile > node ) ; emitNode ( node ) ; } } } writeEmittedFiles = writeJavaScriptAndSourceMapFile ; emit = emitNodeWithMap ; emitStart = recordEmitNodeStartSpan ; emitEnd = recordEmitNodeEndSpan ; emitToken = writeTextWithSpanRecord ; scopeEmitStart = recordScopeNameOfNode ; scopeEmitEnd = recordScopeNameEnd ; writeComment = writeCommentRangeWithMap ; } function writeJavaScriptFile ( emitOutput , writeByteOrderMark ) { writeFile ( compilerHost , diagnostics , jsFilePath , emitOutput , writeByteOrderMark ) ; } function emitTokenText ( tokenKind , startPos , emitFn ? ) { var tokenString = tokenToString ( tokenKind ) ; if ( emitFn ) { emitFn ( ) ; } else { write ( tokenString ) ; } return startPos + tokenString . length ; } function emitOptional ( prefix , node ) { if ( node ) { write ( prefix ) ; emit ( node ) ; } } function emitTrailingCommaIfPresent ( nodeList , isMultiline ) { if ( nodeList . hasTrailingComma ) { write ( "," ) ; if ( isMultiline ) { writeLine ( ) ; } } } function emitCommaList ( nodes , includeTrailingComma , count ? ) { if ( ! ( count >= 0 ) ) { count = nodes . length ; } if ( nodes ) { for ( var i = 0 ; i < count ; i ++ ) { if ( i ) { write ( ", " ) ; } emit ( nodes [ i ] ) ; } if ( includeTrailingComma ) { emitTrailingCommaIfPresent ( nodes , false ) ; } } } function emitMultiLineList ( nodes , includeTrailingComma ) { if ( nodes ) { for ( var i = 0 ; i < nodes . length ; i ++ ) { if ( i ) { write ( "," ) ; } writeLine ( ) ; emit ( nodes [ i ] ) ; } if ( includeTrailingComma ) { emitTrailingCommaIfPresent ( nodes , true ) ; } } } function emitLines ( nodes ) { emitLinesStartingAt ( nodes , 0 ) ; } function emitLinesStartingAt ( nodes , startIndex ) { for ( var i = startIndex ; i < nodes . length ; i ++ ) { writeLine ( ) ; emit ( nodes [ i ] ) ; } } function isBinaryOrOctalIntegerLiteral ( text ) { if ( text . length <= 0 ) { return false ; } if ( text . charCodeAt ( 1 ) === CharacterCodes . B || text . charCodeAt ( 1 ) === CharacterCodes . b || text . charCodeAt ( 1 ) === CharacterCodes . O || text . charCodeAt ( 1 ) === CharacterCodes . o ) { return true ; } return false ; } function emitLiteral ( node ) { var text = getLiteralText ( ) ; if ( compilerOptions . sourceMap && ( node . kind === SyntaxKind . StringLiteral || isTemplateLiteralKind ( node . kind ) ) ) { writer . writeLiteral ( text ) ; } else if ( compilerOptions . target < ScriptTarget . ES6 && node . kind === SyntaxKind . NumericLiteral && isBinaryOrOctalIntegerLiteral ( text ) ) { write ( node . text ) ; } else { write ( text ) ; } function getLiteralText ( ) { if ( compilerOptions . target < ScriptTarget . ES6 && isTemplateLiteralKind ( node . kind ) ) { return getTemplateLiteralAsStringLiteral ( node ) ; } return getSourceTextOfNodeFromSourceFile ( currentSourceFile , node ) ; } } function getTemplateLiteralAsStringLiteral ( node ) { return '"' + escapeString ( node . text ) + '"' ; } function emitTemplateExpression ( node ) { if ( compilerOptions . target >= ScriptTarget . ES6 ) { forEachChild ( node , emit ) ; return ; } Debug . assert ( node . parent . kind !== SyntaxKind . TaggedTemplateExpression ) ; var emitOuterParens = isExpression ( node . parent ) && templateNeedsParens ( node , < Expression > node . parent ) ; if ( emitOuterParens ) { write ( "(" ) ; } emitLiteral ( node . head ) ; forEach ( node . templateSpans , templateSpan => { var needsParens = templateSpan . expression . kind !== SyntaxKind . ParenthesizedExpression && comparePrecedenceToBinaryPlus ( templateSpan . expression ) !== Comparison . GreaterThan ; write ( " + " ) ; if ( needsParens ) { write ( "(" ) ; } emit ( templateSpan . expression ) ; if ( needsParens ) { write ( ")" ) ; } if ( templateSpan . literal . text . length !== 0 ) { write ( " + " ) ; emitLiteral ( templateSpan . literal ) ; } } ) ; if ( emitOuterParens ) { write ( ")" ) ; } function templateNeedsParens ( template , parent ) { switch ( parent . kind ) { case SyntaxKind . CallExpression : case SyntaxKind . NewExpression : return ( < CallExpression > parent ) . expression === template ; case SyntaxKind . ParenthesizedExpression : return false ; case SyntaxKind . TaggedTemplateExpression : Debug . fail ( "Path should be unreachable; tagged templates not supported pre-ES6." ) ; default : return comparePrecedenceToBinaryPlus ( parent ) !== Comparison . LessThan ; } } /**
                 * Returns whether the expression has lesser, greater,
                 * or equal precedence to the binary '+' operator
                 */ function comparePrecedenceToBinaryPlus ( expression ) { Debug . assert ( compilerOptions . target <= ScriptTarget . ES5 ) ; switch ( expression . kind ) { case SyntaxKind . BinaryExpression : switch ( ( < BinaryExpression > expression ) . operator ) { case SyntaxKind . AsteriskToken : case SyntaxKind . SlashToken : case SyntaxKind . PercentToken : return Comparison . GreaterThan ; case SyntaxKind . PlusToken : return Comparison . EqualTo ; default : return Comparison . LessThan ; } case SyntaxKind . ConditionalExpression : return Comparison . LessThan ; default : return Comparison . GreaterThan ; } } } function emitTemplateSpan ( span ) { emit ( span . expression ) ; emit ( span . literal ) ; } function emitExpressionForPropertyName ( node ) { if ( node . kind === SyntaxKind . StringLiteral ) { emitLiteral ( < LiteralExpression > node ) ; } else if ( node . kind === SyntaxKind . ComputedPropertyName ) { emit ( ( < ComputedPropertyName > node ) . expression ) ; } else { write ( "\"" ) ; if ( node . kind === SyntaxKind . NumericLiteral ) { write ( ( < LiteralExpression > node ) . text ) ; } else { writeTextOfNode ( currentSourceFile , node ) ; } write ( "\"" ) ; } } function isNotExpressionIdentifier ( node ) { var parent = node . parent ; switch ( parent . kind ) { case SyntaxKind . Parameter : case SyntaxKind . VariableDeclaration : case SyntaxKind . Property : case SyntaxKind . PropertyAssignment : case SyntaxKind . ShorthandPropertyAssignment : case SyntaxKind . EnumMember : case SyntaxKind . Method : case SyntaxKind . FunctionDeclaration : case SyntaxKind . GetAccessor : case SyntaxKind . SetAccessor : case SyntaxKind . FunctionExpression : case SyntaxKind . ClassDeclaration : case SyntaxKind . InterfaceDeclaration : case SyntaxKind . EnumDeclaration : case SyntaxKind . ModuleDeclaration : case SyntaxKind . ImportDeclaration : return ( < Declaration > parent ) . name === node ; case SyntaxKind . BreakStatement : case SyntaxKind . ContinueStatement : case SyntaxKind . ExportAssignment : return false ; case SyntaxKind . LabeledStatement : return ( < LabeledStatement > node . parent ) . label === node ; case SyntaxKind . CatchClause : return ( < CatchClause > node . parent ) . name === node ; } } function emitExpressionIdentifier ( node ) { var prefix = resolver . getExpressionNamePrefix ( node ) ; if ( prefix ) { write ( prefix ) ; write ( "." ) ; } writeTextOfNode ( currentSourceFile , node ) ; } function emitIdentifier ( node ) { if ( ! isNotExpressionIdentifier ( node ) ) { emitExpressionIdentifier ( node ) ; } else { writeTextOfNode ( currentSourceFile , node ) ; } } function emitThis ( node ) { if ( resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . LexicalThis ) { write ( "_this" ) ; } else { write ( "this" ) ; } } function emitSuper ( node ) { var flags = resolver . getNodeCheckFlags ( node ) ; if ( flags & NodeCheckFlags . SuperInstance ) { write ( "_super.prototype" ) ; } else if ( flags & NodeCheckFlags . SuperStatic ) { write ( "_super" ) ; } else { write ( "super" ) ; } } function emitArrayLiteral ( node ) { if ( node . flags & NodeFlags . MultiLine ) { write ( "[" ) ; increaseIndent ( ) ; emitMultiLineList ( node . elements , true ) ; decreaseIndent ( ) ; writeLine ( ) ; write ( "]" ) ; } else { write ( "[" ) ; emitCommaList ( node . elements , true ) ; write ( "]" ) ; } } function emitObjectLiteral ( node ) { if ( ! node . properties . length ) { write ( "{}" ) ; } else if ( node . flags & NodeFlags . MultiLine ) { write ( "{" ) ; increaseIndent ( ) ; emitMultiLineList ( node . properties , compilerOptions . target >= ScriptTarget . ES5 ) ; decreaseIndent ( ) ; writeLine ( ) ; write ( "}" ) ; } else { write ( "{ " ) ; emitCommaList ( node . properties , compilerOptions . target >= ScriptTarget . ES5 ) ; write ( " }" ) ; } } function emitComputedPropertyName ( node ) { write ( "[" ) ; emit ( node . expression ) ; write ( "]" ) ; } function emitDownlevelMethod ( node ) { if ( ! isObjectLiteralMethod ( node ) ) { return ; } emitLeadingComments ( node ) ; emit ( node . name ) ; write ( ": " ) ; write ( "function " ) ; emitSignatureAndBody ( node ) ; emitTrailingComments ( node ) ; } function emitMethod ( node ) { if ( ! isObjectLiteralMethod ( node ) ) { return ; } emitLeadingComments ( node ) ; emit ( node . name ) ; emitSignatureAndBody ( node ) ; emitTrailingComments ( node ) ; } function emitPropertyAssignment ( node ) { emitLeadingComments ( node ) ; emit ( node . name ) ; write ( ": " ) ; emit ( node . initializer ) ; emitTrailingComments ( node ) ; } function emitDownlevelShorthandPropertyAssignment ( node ) { emitLeadingComments ( node ) ; emit ( node . name ) ; write ( ": " ) ; emitExpressionIdentifier ( node . name ) ; emitTrailingComments ( node ) ; } function emitShorthandPropertyAssignment ( node ) { var prefix = resolver . getExpressionNamePrefix ( node . name ) ; if ( prefix ) { emitDownlevelShorthandPropertyAssignment ( node ) ; } else { emitLeadingComments ( node ) ; emit ( node . name ) ; emitTrailingComments ( node ) ; } } function tryEmitConstantValue ( node ) { var constantValue = resolver . getConstantValue ( node ) ; if ( constantValue !== undefined ) { var propertyName = node . kind === SyntaxKind . PropertyAccessExpression ? declarationNameToString ( ( < PropertyAccessExpression > node ) . name ) : getTextOfNode ( ( < ElementAccessExpression > node ) . argumentExpression ) ; write ( constantValue . toString ( ) + " /* " + propertyName + " */" ) ; return true ; } return false ; } function emitPropertyAccess ( node ) { if ( tryEmitConstantValue ( node ) ) { return ; } emit ( node . expression ) ; write ( "." ) ; emit ( node . name ) ; } function emitQualifiedName ( node ) { emit ( node . left ) ; write ( "." ) ; emit ( node . right ) ; } function emitIndexedAccess ( node ) { if ( tryEmitConstantValue ( node ) ) { return ; } emit ( node . expression ) ; write ( "[" ) ; emit ( node . argumentExpression ) ; write ( "]" ) ; } function emitCallExpression ( node ) { var superCall = false ; if ( node . expression . kind === SyntaxKind . SuperKeyword ) { write ( "_super" ) ; superCall = true ; } else { emit ( node . expression ) ; superCall = node . expression . kind === SyntaxKind . PropertyAccessExpression && ( < PropertyAccessExpression > node . expression ) . expression . kind === SyntaxKind . SuperKeyword ; } if ( superCall ) { write ( ".call(" ) ; emitThis ( node . expression ) ; if ( node . arguments . length ) { write ( ", " ) ; emitCommaList ( node . arguments , false ) ; } write ( ")" ) ; } else { write ( "(" ) ; emitCommaList ( node . arguments , false ) ; write ( ")" ) ; } } function emitNewExpression ( node ) { write ( "new " ) ; emit ( node . expression ) ; if ( node . arguments ) { write ( "(" ) ; emitCommaList ( node . arguments , false ) ; write ( ")" ) ; } } function emitTaggedTemplateExpression ( node ) { Debug . assert ( compilerOptions . target >= ScriptTarget . ES6 , "Trying to emit a tagged template in pre-ES6 mode." ) ; emit ( node . tag ) ; write ( " " ) ; emit ( node . template ) ; } function emitParenExpression ( node ) { if ( node . expression . kind === SyntaxKind . TypeAssertionExpression ) { var operand = ( < TypeAssertion > node . expression ) . expression ; while ( operand . kind == SyntaxKind . TypeAssertionExpression ) { operand = ( < TypeAssertion > operand ) . expression ; } if ( operand . kind !== SyntaxKind . PrefixUnaryExpression && operand . kind !== SyntaxKind . VoidExpression && operand . kind !== SyntaxKind . TypeOfExpression && operand . kind !== SyntaxKind . DeleteExpression && operand . kind !== SyntaxKind . PostfixUnaryExpression && operand . kind !== SyntaxKind . NewExpression && ! ( operand . kind === SyntaxKind . CallExpression && node . parent . kind === SyntaxKind . NewExpression ) && ! ( operand . kind === SyntaxKind . FunctionExpression && node . parent . kind === SyntaxKind . CallExpression ) ) { emit ( operand ) ; return ; } } write ( "(" ) ; emit ( node . expression ) ; write ( ")" ) ; } function emitDeleteExpression ( node ) { write ( tokenToString ( SyntaxKind . DeleteKeyword ) ) ; write ( " " ) ; emit ( node . expression ) ; } function emitVoidExpression ( node ) { write ( tokenToString ( SyntaxKind . VoidKeyword ) ) ; write ( " " ) ; emit ( node . expression ) ; } function emitTypeOfExpression ( node ) { write ( tokenToString ( SyntaxKind . TypeOfKeyword ) ) ; write ( " " ) ; emit ( node . expression ) ; } function emitPrefixUnaryExpression ( node ) { write ( tokenToString ( node . operator ) ) ; if ( node . operand . kind === SyntaxKind . PrefixUnaryExpression ) { var operand = < PrefixUnaryExpression > node . operand ; if ( node . operator === SyntaxKind . PlusToken && ( operand . operator === SyntaxKind . PlusToken || operand . operator === SyntaxKind . PlusPlusToken ) ) { write ( " " ) ; } else if ( node . operator === SyntaxKind . MinusToken && ( operand . operator === SyntaxKind . MinusToken || operand . operator === SyntaxKind . MinusMinusToken ) ) { write ( " " ) ; } } emit ( node . operand ) ; } function emitPostfixUnaryExpression ( node ) { emit ( node . operand ) ; write ( tokenToString ( node . operator ) ) ; } function emitBinaryExpression ( node ) { emit ( node . left ) ; if ( node . operator !== SyntaxKind . CommaToken ) write ( " " ) ; write ( tokenToString ( node . operator ) ) ; write ( " " ) ; emit ( node . right ) ; } function emitConditionalExpression ( node ) { emit ( node . condition ) ; write ( " ? " ) ; emit ( node . whenTrue ) ; write ( " : " ) ; emit ( node . whenFalse ) ; } function emitBlock ( node ) { emitToken ( SyntaxKind . OpenBraceToken , node . pos ) ; increaseIndent ( ) ; scopeEmitStart ( node . parent ) ; if ( node . kind === SyntaxKind . ModuleBlock ) { Debug . assert ( node . parent . kind === SyntaxKind . ModuleDeclaration ) ; emitCaptureThisForNodeIfNecessary ( node . parent ) ; } emitLines ( node . statements ) ; decreaseIndent ( ) ; writeLine ( ) ; emitToken ( SyntaxKind . CloseBraceToken , node . statements . end ) ; scopeEmitEnd ( ) ; } function emitEmbeddedStatement ( node ) { if ( node . kind === SyntaxKind . Block ) { write ( " " ) ; emit ( < Block > node ) ; } else { increaseIndent ( ) ; writeLine ( ) ; emit ( node ) ; decreaseIndent ( ) ; } } function emitExpressionStatement ( node ) { var isArrowExpression = node . expression . kind === SyntaxKind . ArrowFunction ; emitLeadingComments ( node ) ; if ( isArrowExpression ) write ( "(" ) ; emit ( node . expression ) ; if ( isArrowExpression ) write ( ")" ) ; write ( ";" ) ; emitTrailingComments ( node ) ; } function emitIfStatement ( node ) { emitLeadingComments ( node ) ; var endPos = emitToken ( SyntaxKind . IfKeyword , node . pos ) ; write ( " " ) ; endPos = emitToken ( SyntaxKind . OpenParenToken , endPos ) ; emit ( node . expression ) ; emitToken ( SyntaxKind . CloseParenToken , node . expression . end ) ; emitEmbeddedStatement ( node . thenStatement ) ; if ( node . elseStatement ) { writeLine ( ) ; emitToken ( SyntaxKind . ElseKeyword , node . thenStatement . end ) ; if ( node . elseStatement . kind === SyntaxKind . IfStatement ) { write ( " " ) ; emit ( node . elseStatement ) ; } else { emitEmbeddedStatement ( node . elseStatement ) ; } } emitTrailingComments ( node ) ; } function emitDoStatement ( node ) { write ( "do" ) ; emitEmbeddedStatement ( node . statement ) ; if ( node . statement . kind === SyntaxKind . Block ) { write ( " " ) ; } else { writeLine ( ) ; } write ( "while (" ) ; emit ( node . expression ) ; write ( ");" ) ; } function emitWhileStatement ( node ) { write ( "while (" ) ; emit ( node . expression ) ; write ( ")" ) ; emitEmbeddedStatement ( node . statement ) ; } function emitForStatement ( node ) { var endPos = emitToken ( SyntaxKind . ForKeyword , node . pos ) ; write ( " " ) ; endPos = emitToken ( SyntaxKind . OpenParenToken , endPos ) ; if ( node . declarations ) { if ( node . declarations [ 0 ] && isLet ( node . declarations [ 0 ] ) ) { emitToken ( SyntaxKind . LetKeyword , endPos ) ; } else if ( node . declarations [ 0 ] && isConst ( node . declarations [ 0 ] ) ) { emitToken ( SyntaxKind . ConstKeyword , endPos ) ; } else { emitToken ( SyntaxKind . VarKeyword , endPos ) ; } write ( " " ) ; emitCommaList ( node . declarations , false ) ; } if ( node . initializer ) { emit ( node . initializer ) ; } write ( ";" ) ; emitOptional ( " " , node . condition ) ; write ( ";" ) ; emitOptional ( " " , node . iterator ) ; write ( ")" ) ; emitEmbeddedStatement ( node . statement ) ; } function emitForInStatement ( node ) { var endPos = emitToken ( SyntaxKind . ForKeyword , node . pos ) ; write ( " " ) ; endPos = emitToken ( SyntaxKind . OpenParenToken , endPos ) ; if ( node . declarations ) { if ( node . declarations . length >= 1 ) { var decl = node . declarations [ 0 ] ; if ( isLet ( decl ) ) { emitToken ( SyntaxKind . LetKeyword , endPos ) ; } else { emitToken ( SyntaxKind . VarKeyword , endPos ) ; } write ( " " ) ; emit ( decl ) ; } } else { emit ( node . variable ) ; } write ( " in " ) ; emit ( node . expression ) ; emitToken ( SyntaxKind . CloseParenToken , node . expression . end ) ; emitEmbeddedStatement ( node . statement ) ; } function emitBreakOrContinueStatement ( node ) { emitToken ( node . kind === SyntaxKind . BreakStatement ? SyntaxKind . BreakKeyword : SyntaxKind . ContinueKeyword , node . pos ) ; emitOptional ( " " , node . label ) ; write ( ";" ) ; } function emitReturnStatement ( node ) { emitLeadingComments ( node ) ; emitToken ( SyntaxKind . ReturnKeyword , node . pos ) ; emitOptional ( " " , node . expression ) ; write ( ";" ) ; emitTrailingComments ( node ) ; } function emitWithStatement ( node ) { write ( "with (" ) ; emit ( node . expression ) ; write ( ")" ) ; emitEmbeddedStatement ( node . statement ) ; } function emitSwitchStatement ( node ) { var endPos = emitToken ( SyntaxKind . SwitchKeyword , node . pos ) ; write ( " " ) ; emitToken ( SyntaxKind . OpenParenToken , endPos ) ; emit ( node . expression ) ; endPos = emitToken ( SyntaxKind . CloseParenToken , node . expression . end ) ; write ( " " ) ; emitToken ( SyntaxKind . OpenBraceToken , endPos ) ; increaseIndent ( ) ; emitLines ( node . clauses ) ; decreaseIndent ( ) ; writeLine ( ) ; emitToken ( SyntaxKind . CloseBraceToken , node . clauses . end ) ; } function isOnSameLine ( node1 , node2 ) { return getLineOfLocalPosition ( currentSourceFile , skipTrivia ( currentSourceFile . text , node1 . pos ) ) === getLineOfLocalPosition ( currentSourceFile , skipTrivia ( currentSourceFile . text , node2 . pos ) ) ; } function emitCaseOrDefaultClause ( node ) { if ( node . kind === SyntaxKind . CaseClause ) { write ( "case " ) ; emit ( ( < CaseClause > node ) . expression ) ; write ( ":" ) ; } else { write ( "default:" ) ; } if ( node . statements . length === 1 && isOnSameLine ( node , node . statements [ 0 ] ) ) { write ( " " ) ; emit ( node . statements [ 0 ] ) ; } else { increaseIndent ( ) ; emitLines ( node . statements ) ; decreaseIndent ( ) ; } } function emitThrowStatement ( node ) { write ( "throw " ) ; emit ( node . expression ) ; write ( ";" ) ; } function emitTryStatement ( node ) { write ( "try " ) ; emit ( node . tryBlock ) ; emit ( node . catchClause ) ; if ( node . finallyBlock ) { writeLine ( ) ; write ( "finally " ) ; emit ( node . finallyBlock ) ; } } function emitCatchClause ( node ) { writeLine ( ) ; var endPos = emitToken ( SyntaxKind . CatchKeyword , node . pos ) ; write ( " " ) ; emitToken ( SyntaxKind . OpenParenToken , endPos ) ; emit ( node . name ) ; emitToken ( SyntaxKind . CloseParenToken , node . name . end ) ; write ( " " ) ; emitBlock ( node . block ) ; } function emitDebuggerStatement ( node ) { emitToken ( SyntaxKind . DebuggerKeyword , node . pos ) ; write ( ";" ) ; } function emitLabelledStatement ( node ) { emit ( node . label ) ; write ( ": " ) ; emit ( node . statement ) ; } function getContainingModule ( node ) { do { node = node . parent ; } while ( node && node . kind !== SyntaxKind . ModuleDeclaration ) ; return < ModuleDeclaration > node ; } function emitModuleMemberName ( node ) { emitStart ( node . name ) ; if ( node . flags & NodeFlags . Export ) { var container = getContainingModule ( node ) ; write ( container ? resolver . getLocalNameOfContainer ( container ) : "exports" ) ; write ( "." ) ; } emitNode ( node . name ) ; emitEnd ( node . name ) ; } function emitVariableDeclaration ( node ) { emitLeadingComments ( node ) ; emitModuleMemberName ( node ) ; emitOptional ( " = " , node . initializer ) ; emitTrailingComments ( node ) ; } function emitVariableStatement ( node ) { emitLeadingComments ( node ) ; if ( ! ( node . flags & NodeFlags . Export ) ) { if ( isLet ( node ) ) { write ( "let " ) ; } else if ( isConst ( node ) ) { write ( "const " ) ; } else { write ( "var " ) ; } } emitCommaList ( node . declarations , false ) ; write ( ";" ) ; emitTrailingComments ( node ) ; } function emitParameter ( node ) { emitLeadingComments ( node ) ; emit ( node . name ) ; emitTrailingComments ( node ) ; } function emitDefaultValueAssignments ( node ) { forEach ( node . parameters , param => { if ( param . initializer ) { writeLine ( ) ; emitStart ( param ) ; write ( "if (" ) ; emitNode ( param . name ) ; write ( " === void 0)" ) ; emitEnd ( param ) ; write ( " { " ) ; emitStart ( param ) ; emitNode ( param . name ) ; write ( " = " ) ; emitNode ( param . initializer ) ; emitEnd ( param ) ; write ( "; }" ) ; } } ) ; } function emitRestParameter ( node ) { if ( hasRestParameters ( node ) ) { var restIndex = node . parameters . length - 1 ; var restParam = node . parameters [ restIndex ] ; writeLine ( ) ; emitLeadingComments ( restParam ) ; emitStart ( restParam ) ; write ( "var " ) ; emitNode ( restParam . name ) ; write ( " = [];" ) ; emitEnd ( restParam ) ; emitTrailingComments ( restParam ) ; writeLine ( ) ; write ( "for (" ) ; emitStart ( restParam ) ; write ( "var _i = " + restIndex + ";" ) ; emitEnd ( restParam ) ; write ( " " ) ; emitStart ( restParam ) ; write ( "_i < arguments.length;" ) ; emitEnd ( restParam ) ; write ( " " ) ; emitStart ( restParam ) ; write ( "_i++" ) ; emitEnd ( restParam ) ; write ( ") {" ) ; increaseIndent ( ) ; writeLine ( ) ; emitStart ( restParam ) ; emitNode ( restParam . name ) ; write ( "[_i - " + restIndex + "] = arguments[_i];" ) ; emitEnd ( restParam ) ; decreaseIndent ( ) ; writeLine ( ) ; write ( "}" ) ; } } function emitAccessor ( node ) { emitLeadingComments ( node ) ; write ( node . kind === SyntaxKind . GetAccessor ? "get " : "set " ) ; emit ( node . name ) ; emitSignatureAndBody ( node ) ; emitTrailingComments ( node ) ; } function emitFunctionDeclaration ( node ) { if ( ! node . body ) { return emitPinnedOrTripleSlashComments ( node ) ; } if ( node . kind !== SyntaxKind . Method ) { emitLeadingComments ( node ) ; } write ( "function " ) ; if ( node . kind === SyntaxKind . FunctionDeclaration || ( node . kind === SyntaxKind . FunctionExpression && node . name ) ) { emit ( node . name ) ; } emitSignatureAndBody ( node ) ; if ( node . kind !== SyntaxKind . Method ) { emitTrailingComments ( node ) ; } } function emitCaptureThisForNodeIfNecessary ( node ) { if ( resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . CaptureThis ) { writeLine ( ) ; emitStart ( node ) ; write ( "var _this = this;" ) ; emitEnd ( node ) ; } } function emitSignatureParameters ( node ) { increaseIndent ( ) ; write ( "(" ) ; if ( node ) { emitCommaList ( node . parameters , false , node . parameters . length - ( hasRestParameters ( node ) ? 1 : 0 ) ) ; } write ( ")" ) ; decreaseIndent ( ) ; } function emitSignatureAndBody ( node ) { emitSignatureParameters ( node ) ; write ( " {" ) ; scopeEmitStart ( node ) ; increaseIndent ( ) ; emitDetachedComments ( node . body . kind === SyntaxKind . Block ? ( < Block > node . body ) . statements : node . body ) ; var startIndex = 0 ; if ( node . body . kind === SyntaxKind . Block ) { startIndex = emitDirectivePrologues ( ( < Block > node . body ) . statements , true ) ; } var outPos = writer . getTextPos ( ) ; emitCaptureThisForNodeIfNecessary ( node ) ; emitDefaultValueAssignments ( node ) ; emitRestParameter ( node ) ; if ( node . body . kind !== SyntaxKind . Block && outPos === writer . getTextPos ( ) ) { decreaseIndent ( ) ; write ( " " ) ; emitStart ( node . body ) ; write ( "return " ) ; emitNode ( node . body ) ; emitEnd ( node . body ) ; write ( "; " ) ; emitStart ( node . body ) ; write ( "}" ) ; emitEnd ( node . body ) ; } else { if ( node . body . kind === SyntaxKind . Block ) { emitLinesStartingAt ( ( < Block > node . body ) . statements , startIndex ) ; } else { writeLine ( ) ; emitLeadingComments ( node . body ) ; write ( "return " ) ; emit ( node . body ) ; write ( ";" ) ; emitTrailingComments ( node . body ) ; } writeLine ( ) ; if ( node . body . kind === SyntaxKind . Block ) { emitLeadingCommentsOfPosition ( ( < Block > node . body ) . statements . end ) ; decreaseIndent ( ) ; emitToken ( SyntaxKind . CloseBraceToken , ( < Block > node . body ) . statements . end ) ; } else { decreaseIndent ( ) ; emitStart ( node . body ) ; write ( "}" ) ; emitEnd ( node . body ) ; } } scopeEmitEnd ( ) ; if ( node . flags & NodeFlags . Export ) { writeLine ( ) ; emitStart ( node ) ; emitModuleMemberName ( node ) ; write ( " = " ) ; emit ( node . name ) ; emitEnd ( node ) ; write ( ";" ) ; } } function findInitialSuperCall ( ctor ) { if ( ctor . body ) { var statement = ( < Block > ctor . body ) . statements [ 0 ] ; if ( statement && statement . kind === SyntaxKind . ExpressionStatement ) { var expr = ( < ExpressionStatement > statement ) . expression ; if ( expr && expr . kind === SyntaxKind . CallExpression ) { var func = ( < CallExpression > expr ) . expression ; if ( func && func . kind === SyntaxKind . SuperKeyword ) { return < ExpressionStatement > statement ; } } } } } function emitParameterPropertyAssignments ( node ) { forEach ( node . parameters , param => { if ( param . flags & NodeFlags . AccessibilityModifier ) { writeLine ( ) ; emitStart ( param ) ; emitStart ( param . name ) ; write ( "this." ) ; emitNode ( param . name ) ; emitEnd ( param . name ) ; write ( " = " ) ; emit ( param . name ) ; write ( ";" ) ; emitEnd ( param ) ; } } ) ; } function emitMemberAccessForPropertyName ( memberName ) { if ( memberName . kind === SyntaxKind . StringLiteral || memberName . kind === SyntaxKind . NumericLiteral ) { write ( "[" ) ; emitNode ( memberName ) ; write ( "]" ) ; } else if ( memberName . kind === SyntaxKind . ComputedPropertyName ) { emitComputedPropertyName ( < ComputedPropertyName > memberName ) ; } else { write ( "." ) ; emitNode ( memberName ) ; } } function emitMemberAssignments ( node , staticFlag ) { forEach ( node . members , member => { if ( member . kind === SyntaxKind . Property && ( member . flags & NodeFlags . Static ) === staticFlag && ( < PropertyDeclaration > member ) . initializer ) { writeLine ( ) ; emitLeadingComments ( member ) ; emitStart ( member ) ; emitStart ( ( < PropertyDeclaration > member ) . name ) ; if ( staticFlag ) { emitNode ( node . name ) ; } else { write ( "this" ) ; } emitMemberAccessForPropertyName ( ( < PropertyDeclaration > member ) . name ) ; emitEnd ( ( < PropertyDeclaration > member ) . name ) ; write ( " = " ) ; emit ( ( < PropertyDeclaration > member ) . initializer ) ; write ( ";" ) ; emitEnd ( member ) ; emitTrailingComments ( member ) ; } } ) ; } function emitMemberFunctions ( node ) { writeLine ( ) ; write ( 'var d = __define,c=' ) ; emitNode ( node . name ) ; write ( ';p=c.prototype;' ) ; forEach ( node . members , member => { if ( member . kind === SyntaxKind . Method ) { if ( ! ( < MethodDeclaration > member ) . body ) { return emitPinnedOrTripleSlashComments ( member ) ; } writeLine ( ) ; emitLeadingComments ( member ) ; emitStart ( member ) ; emitStart ( ( < MethodDeclaration > member ) . name ) ; if ( ! ( member . flags & NodeFlags . Static ) ) { write ( "p" ) ; } else emitNode ( node . name ) ; emitMemberAccessForPropertyName ( ( < MethodDeclaration > member ) . name ) ; emitEnd ( ( < MethodDeclaration > member ) . name ) ; write ( " = " ) ; emitStart ( member ) ; emitFunctionDeclaration ( < MethodDeclaration > member ) ; emitEnd ( member ) ; emitEnd ( member ) ; write ( ";" ) ; emitTrailingComments ( member ) ; } else if ( member . kind === SyntaxKind . GetAccessor || member . kind === SyntaxKind . SetAccessor ) { var accessors = getAllAccessorDeclarations ( node , < AccessorDeclaration > member ) ; if ( member === accessors . firstAccessor ) { writeLine ( ) ; emitStart ( member ) ; write ( "d(" ) ; emitStart ( ( < AccessorDeclaration > member ) . name ) ; if ( ! ( member . flags & NodeFlags . Static ) ) { write ( "p" ) ; } else emitNode ( node . name ) ; write ( ", " ) ; emitExpressionForPropertyName ( ( < AccessorDeclaration > member ) . name ) ; emitEnd ( ( < AccessorDeclaration > member ) . name ) ; increaseIndent ( ) ; if ( accessors . getAccessor ) { writeLine ( ) ; emitLeadingComments ( accessors . getAccessor ) ; emitStart ( accessors . getAccessor ) ; write ( ",function " ) ; emitSignatureAndBody ( accessors . getAccessor ) ; emitEnd ( accessors . getAccessor ) ; emitTrailingComments ( accessors . getAccessor ) ; } else if ( accessors . setAccessor ) { write ( ",undefined" ) ; } if ( accessors . setAccessor ) { writeLine ( ) ; emitLeadingComments ( accessors . setAccessor ) ; emitStart ( accessors . setAccessor ) ; write ( ",function " ) ; emitSignatureAndBody ( accessors . setAccessor ) ; emitEnd ( accessors . setAccessor ) ; emitTrailingComments ( accessors . setAccessor ) ; } decreaseIndent ( ) ; writeLine ( ) ; write ( ");" ) ; emitEnd ( member ) ; } } } ) ; } function emitClassDeclaration ( node ) { emitLeadingComments ( node ) ; write ( "var " ) ; emit ( node . name ) ; write ( " = (function (" ) ; var baseTypeNode = getClassBaseTypeNode ( node ) ; if ( baseTypeNode ) { write ( "_super" ) ; } write ( ") {" ) ; increaseIndent ( ) ; scopeEmitStart ( node ) ; if ( baseTypeNode ) { writeLine ( ) ; emitStart ( baseTypeNode ) ; write ( "__extends(" ) ; emit ( node . name ) ; write ( ", _super);" ) ; emitEnd ( baseTypeNode ) ; } writeLine ( ) ; emitConstructorOfClass ( ) ; emitMemberFunctions ( node ) ; emitMemberAssignments ( node , NodeFlags . Static ) ; writeLine ( ) ; function emitClassReturnStatement ( ) { write ( "return " ) ; emitNode ( node . name ) ; } emitToken ( SyntaxKind . CloseBraceToken , node . members . end , emitClassReturnStatement ) ; write ( ";" ) ; decreaseIndent ( ) ; writeLine ( ) ; emitToken ( SyntaxKind . CloseBraceToken , node . members . end ) ; scopeEmitEnd ( ) ; emitStart ( node ) ; write ( ")(" ) ; if ( baseTypeNode ) { emit ( baseTypeNode . typeName ) ; } write ( ");" ) ; emitEnd ( node ) ; if ( node . flags & NodeFlags . Export ) { writeLine ( ) ; emitStart ( node ) ; emitModuleMemberName ( node ) ; write ( " = " ) ; emit ( node . name ) ; emitEnd ( node ) ; write ( ";" ) ; } var checker = program . getTypeChecker ( true ) ; var fullName = checker . getFullyQualifiedName ( node . symbol ) ; var interfaces = { } ; getImplementedInterfaces ( node , interfaces , true ) ; writeLine ( ) ; write ( 'lark.registerClass(' ) ; emit ( node . name ) ; write ( ',"' + fullName + '"' ) ; var interfacesArray = Object . keys ( interfaces ) ; if ( interfacesArray . length > 0 ) { write ( ',' ) ; write ( JSON . stringify ( interfacesArray ) ) ; } write ( ');' ) ; writeLine ( ) ; emitTrailingComments ( node ) ; function getImplementedInterfaces ( node , names , isClass = true ) { var superInterfaces = null ; if ( isClass ) superInterfaces = ts . getClassImplementedTypeNodes ( < ClassDeclaration > node ) ; else superInterfaces = ts . getInterfaceBaseTypeNodes ( < InterfaceDeclaration > node ) ; if ( superInterfaces ) { superInterfaces . forEach ( sp => { var interfaceType = checker . getTypeAtLocation ( sp ) ; if ( interfaceType . flags & TypeFlags . Interface ) { var fullname = checker . getFullyQualifiedName ( interfaceType . symbol ) ; names [ fullname ] = true ; if ( interfaceType . symbol . declarations ) { interfaceType . symbol . declarations . forEach ( d => getImplementedInterfaces ( d , names , ! ! ( interfaceType . flags & TypeFlags . Class ) ) ) ; } } } ) ; } } function emitConstructorOfClass ( ) { forEach ( node . members , member => { if ( member . kind === SyntaxKind . Constructor && ! ( < ConstructorDeclaration > member ) . body ) { emitPinnedOrTripleSlashComments ( member ) ; } } ) ; var ctor = getFirstConstructorWithBody ( node ) ; if ( ctor ) { emitLeadingComments ( ctor ) ; } emitStart ( < Node > ctor || node ) ; write ( "function " ) ; emit ( node . name ) ; emitSignatureParameters ( ctor ) ; write ( " {" ) ; scopeEmitStart ( node , "constructor" ) ; increaseIndent ( ) ; if ( ctor ) { emitDetachedComments ( ( < Block > ctor . body ) . statements ) ; } emitCaptureThisForNodeIfNecessary ( node ) ; if ( ctor ) { emitDefaultValueAssignments ( ctor ) ; emitRestParameter ( ctor ) ; if ( baseTypeNode ) { var superCall = findInitialSuperCall ( ctor ) ; if ( superCall ) { writeLine ( ) ; emit ( superCall ) ; } } emitParameterPropertyAssignments ( ctor ) ; } else { if ( baseTypeNode ) { writeLine ( ) ; emitStart ( baseTypeNode ) ; write ( "_super.apply(this, arguments);" ) ; emitEnd ( baseTypeNode ) ; } } emitMemberAssignments ( node , 0 ) ; if ( ctor ) { var statements = ( < Block > ctor . body ) . statements ; if ( superCall ) statements = statements . slice ( 1 ) ; emitLines ( statements ) ; } writeLine ( ) ; if ( ctor ) { emitLeadingCommentsOfPosition ( ( < Block > ctor . body ) . statements . end ) ; } decreaseIndent ( ) ; emitToken ( SyntaxKind . CloseBraceToken , ctor ? ( < Block > ctor . body ) . statements . end : node . members . end ) ; scopeEmitEnd ( ) ; emitEnd ( < Node > ctor || node ) ; if ( ctor ) { emitTrailingComments ( ctor ) ; } } } function emitInterfaceDeclaration ( node ) { emitPinnedOrTripleSlashComments ( node ) ; } function emitEnumDeclaration ( node ) { var isConstEnum = isConst ( node ) ; if ( isConstEnum && ! compilerOptions . preserveConstEnums ) { return ; } emitLeadingComments ( node ) ; if ( ! ( node . flags & NodeFlags . Export ) ) { emitStart ( node ) ; write ( "var " ) ; emit ( node . name ) ; emitEnd ( node ) ; write ( ";" ) ; } writeLine ( ) ; emitStart ( node ) ; write ( "(function (" ) ; emitStart ( node . name ) ; write ( resolver . getLocalNameOfContainer ( node ) ) ; emitEnd ( node . name ) ; write ( ") {" ) ; increaseIndent ( ) ; scopeEmitStart ( node ) ; emitEnumMemberDeclarations ( isConstEnum ) ; decreaseIndent ( ) ; writeLine ( ) ; emitToken ( SyntaxKind . CloseBraceToken , node . members . end ) ; scopeEmitEnd ( ) ; write ( ")(" ) ; emitModuleMemberName ( node ) ; write ( " || (" ) ; emitModuleMemberName ( node ) ; write ( " = {}));" ) ; emitEnd ( node ) ; if ( node . flags & NodeFlags . Export ) { writeLine ( ) ; emitStart ( node ) ; write ( "var " ) ; emit ( node . name ) ; write ( " = " ) ; emitModuleMemberName ( node ) ; emitEnd ( node ) ; write ( ";" ) ; } emitTrailingComments ( node ) ; function emitEnumMemberDeclarations ( isConstEnum ) { forEach ( node . members , member => { writeLine ( ) ; emitLeadingComments ( member ) ; emitStart ( member ) ; write ( resolver . getLocalNameOfContainer ( node ) ) ; write ( "[" ) ; write ( resolver . getLocalNameOfContainer ( node ) ) ; write ( "[" ) ; emitExpressionForPropertyName ( member . name ) ; write ( "] = " ) ; if ( member . initializer && ! isConstEnum ) { emit ( member . initializer ) ; } else { write ( resolver . getEnumMemberValue ( member ) . toString ( ) ) ; } write ( "] = " ) ; emitExpressionForPropertyName ( member . name ) ; emitEnd ( member ) ; write ( ";" ) ; emitTrailingComments ( member ) ; } ) ; } } function getInnerMostModuleDeclarationFromDottedModule ( moduleDeclaration ) { if ( moduleDeclaration . body . kind === SyntaxKind . ModuleDeclaration ) { var recursiveInnerModule = getInnerMostModuleDeclarationFromDottedModule ( < ModuleDeclaration > moduleDeclaration . body ) ; return recursiveInnerModule || < ModuleDeclaration > moduleDeclaration . body ; } } function emitModuleDeclaration ( node ) { var shouldEmit = getModuleInstanceState ( node ) === ModuleInstanceState . Instantiated || ( getModuleInstanceState ( node ) === ModuleInstanceState . ConstEnumOnly && compilerOptions . preserveConstEnums ) ; if ( ! shouldEmit ) { return emitPinnedOrTripleSlashComments ( node ) ; } emitLeadingComments ( node ) ; emitStart ( node ) ; write ( "var " ) ; emit ( node . name ) ; write ( ";" ) ; emitEnd ( node ) ; writeLine ( ) ; emitStart ( node ) ; write ( "(function (" ) ; emitStart ( node . name ) ; write ( resolver . getLocalNameOfContainer ( node ) ) ; emitEnd ( node . name ) ; write ( ") " ) ; if ( node . body . kind === SyntaxKind . ModuleBlock ) { emit ( node . body ) ; } else { write ( "{" ) ; increaseIndent ( ) ; scopeEmitStart ( node ) ; emitCaptureThisForNodeIfNecessary ( node ) ; writeLine ( ) ; emit ( node . body ) ; decreaseIndent ( ) ; writeLine ( ) ; var moduleBlock = < ModuleBlock > getInnerMostModuleDeclarationFromDottedModule ( node ) . body ; emitToken ( SyntaxKind . CloseBraceToken , moduleBlock . statements . end ) ; scopeEmitEnd ( ) ; } write ( ")(" ) ; if ( node . flags & NodeFlags . Export ) { emit ( node . name ) ; write ( " = " ) ; } emitModuleMemberName ( node ) ; write ( " || (" ) ; emitModuleMemberName ( node ) ; write ( " = {}));" ) ; emitEnd ( node ) ; emitTrailingComments ( node ) ; } function emitImportDeclaration ( node ) { var emitImportDeclaration = resolver . isReferencedImportDeclaration ( node ) ; if ( ! emitImportDeclaration ) { emitImportDeclaration = ! isExternalModule ( currentSourceFile ) && resolver . isTopLevelValueImportWithEntityName ( node ) ; } if ( emitImportDeclaration ) { if ( isExternalModuleImportDeclaration ( node ) && node . parent . kind === SyntaxKind . SourceFile && compilerOptions . module === ModuleKind . AMD ) { if ( node . flags & NodeFlags . Export ) { writeLine ( ) ; emitLeadingComments ( node ) ; emitStart ( node ) ; emitModuleMemberName ( node ) ; write ( " = " ) ; emit ( node . name ) ; write ( ";" ) ; emitEnd ( node ) ; emitTrailingComments ( node ) ; } } else { writeLine ( ) ; emitLeadingComments ( node ) ; emitStart ( node ) ; if ( ! ( node . flags & NodeFlags . Export ) ) write ( "var " ) ; emitModuleMemberName ( node ) ; write ( " = " ) ; if ( isInternalModuleImportDeclaration ( node ) ) { emit ( node . moduleReference ) ; } else { var literal = < LiteralExpression > getExternalModuleImportDeclarationExpression ( node ) ; write ( "require(" ) ; emitStart ( literal ) ; emitLiteral ( literal ) ; emitEnd ( literal ) ; emitToken ( SyntaxKind . CloseParenToken , literal . end ) ; } write ( ";" ) ; emitEnd ( node ) ; emitTrailingComments ( node ) ; } } } function getExternalImportDeclarations ( node ) { var result = [ ] ; forEach ( node . statements , statement => { if ( isExternalModuleImportDeclaration ( statement ) && resolver . isReferencedImportDeclaration ( < ImportDeclaration > statement ) ) { result . push ( < ImportDeclaration > statement ) ; } } ) ; return result ; } function getFirstExportAssignment ( sourceFile ) { return forEach ( sourceFile . statements , node => { if ( node . kind === SyntaxKind . ExportAssignment ) { return < ExportAssignment > node ; } } ) ; } function emitAMDModule ( node , startIndex ) { var imports = getExternalImportDeclarations ( node ) ; writeLine ( ) ; write ( "define(" ) ; if ( node . amdModuleName ) { write ( "\"" + node . amdModuleName + "\", " ) ; } write ( "[\"require\", \"exports\"" ) ; forEach ( imports , imp => { write ( ", " ) ; emitLiteral ( < LiteralExpression > getExternalModuleImportDeclarationExpression ( imp ) ) ; } ) ; forEach ( node . amdDependencies , amdDependency => { var text = "\"" + amdDependency + "\"" ; write ( ", " ) ; write ( text ) ; } ) ; write ( "], function (require, exports" ) ; forEach ( imports , imp => { write ( ", " ) ; emit ( imp . name ) ; } ) ; write ( ") {" ) ; increaseIndent ( ) ; emitCaptureThisForNodeIfNecessary ( node ) ; emitLinesStartingAt ( node . statements , startIndex ) ; var exportName = resolver . getExportAssignmentName ( node ) ; if ( exportName ) { writeLine ( ) ; var exportAssignement = getFirstExportAssignment ( node ) ; emitStart ( exportAssignement ) ; write ( "return " ) ; emitStart ( exportAssignement . exportName ) ; write ( exportName ) ; emitEnd ( exportAssignement . exportName ) ; write ( ";" ) ; emitEnd ( exportAssignement ) ; } decreaseIndent ( ) ; writeLine ( ) ; write ( "});" ) ; } function emitCommonJSModule ( node , startIndex ) { emitCaptureThisForNodeIfNecessary ( node ) ; emitLinesStartingAt ( node . statements , startIndex ) ; var exportName = resolver . getExportAssignmentName ( node ) ; if ( exportName ) { writeLine ( ) ; var exportAssignement = getFirstExportAssignment ( node ) ; emitStart ( exportAssignement ) ; write ( "module.exports = " ) ; emitStart ( exportAssignement . exportName ) ; write ( exportName ) ; emitEnd ( exportAssignement . exportName ) ; write ( ";" ) ; emitEnd ( exportAssignement ) ; } } function emitDirectivePrologues ( statements , startWithNewLine ) { for ( var i = 0 ; i < statements . length ; ++ i ) { if ( isPrologueDirective ( statements [ i ] ) ) { if ( startWithNewLine || i > 0 ) { writeLine ( ) ; } emit ( statements [ i ] ) ; } else { return i ; } } return statements . length ; } function emitSourceFile ( node ) { currentSourceFile = node ; writeLine ( ) ; emitDetachedComments ( node ) ; var startIndex = emitDirectivePrologues ( node . statements , false ) ; if ( ! extendsEmitted && resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . EmitExtends ) { writeLine ( ) ; write ( "var __extends = this.__extends || function (d, b) {" ) ; increaseIndent ( ) ; writeLine ( ) ; write ( "for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];" ) ; writeLine ( ) ; write ( "function __() { this.constructor = d; }" ) ; writeLine ( ) ; write ( "__.prototype = b.prototype;" ) ; writeLine ( ) ; write ( "d.prototype = new __();" ) ; decreaseIndent ( ) ; writeLine ( ) ; write ( "};" ) ; extendsEmitted = true ; } if ( ! defineEmitted ) { writeLine ( ) ; write ( 'var __define = this.__define || function (o, p, g, s) { \n  Object.defineProperty(o, p, { configurable:true, enumerable:true, get:g,set:s }) };' ) ; defineEmitted = true ; } if ( isExternalModule ( node ) ) { if ( compilerOptions . module === ModuleKind . AMD ) { emitAMDModule ( node , startIndex ) ; } else { emitCommonJSModule ( node , startIndex ) ; } } else { emitCaptureThisForNodeIfNecessary ( node ) ; emitLinesStartingAt ( node . statements , startIndex ) ; } emitLeadingComments ( node . endOfFileToken ) ; } function emitNode ( node ) { if ( ! node ) { return ; } if ( node . flags & NodeFlags . Ambient ) { return emitPinnedOrTripleSlashComments ( node ) ; } switch ( node . kind ) { case SyntaxKind . Identifier : return emitIdentifier ( < Identifier > node ) ; case SyntaxKind . Parameter : return emitParameter ( < ParameterDeclaration > node ) ; case SyntaxKind . GetAccessor : case SyntaxKind . SetAccessor : return emitAccessor ( < AccessorDeclaration > node ) ; case SyntaxKind . ThisKeyword : return emitThis ( node ) ; case SyntaxKind . SuperKeyword : return emitSuper ( node ) ; case SyntaxKind . NullKeyword : return write ( "null" ) ; case SyntaxKind . TrueKeyword : return write ( "true" ) ; case SyntaxKind . FalseKeyword : return write ( "false" ) ; case SyntaxKind . NumericLiteral : case SyntaxKind . StringLiteral : case SyntaxKind . RegularExpressionLiteral : case SyntaxKind . NoSubstitutionTemplateLiteral : case SyntaxKind . TemplateHead : case SyntaxKind . TemplateMiddle : case SyntaxKind . TemplateTail : return emitLiteral ( < LiteralExpression > node ) ; case SyntaxKind . TemplateExpression : return emitTemplateExpression ( < TemplateExpression > node ) ; case SyntaxKind . TemplateSpan : return emitTemplateSpan ( < TemplateSpan > node ) ; case SyntaxKind . QualifiedName : return emitQualifiedName ( < QualifiedName > node ) ; case SyntaxKind . ArrayLiteralExpression : return emitArrayLiteral ( < ArrayLiteralExpression > node ) ; case SyntaxKind . ObjectLiteralExpression : return emitObjectLiteral ( < ObjectLiteralExpression > node ) ; case SyntaxKind . PropertyAssignment : return emitPropertyAssignment ( < PropertyDeclaration > node ) ; case SyntaxKind . ComputedPropertyName : return emitComputedPropertyName ( < ComputedPropertyName > node ) ; case SyntaxKind . PropertyAccessExpression : return emitPropertyAccess ( < PropertyAccessExpression > node ) ; case SyntaxKind . ElementAccessExpression : return emitIndexedAccess ( < ElementAccessExpression > node ) ; case SyntaxKind . CallExpression : return emitCallExpression ( < CallExpression > node ) ; case SyntaxKind . NewExpression : return emitNewExpression ( < NewExpression > node ) ; case SyntaxKind . TaggedTemplateExpression : return emitTaggedTemplateExpression ( < TaggedTemplateExpression > node ) ; case SyntaxKind . TypeAssertionExpression : return emit ( ( < TypeAssertion > node ) . expression ) ; case SyntaxKind . ParenthesizedExpression : return emitParenExpression ( < ParenthesizedExpression > node ) ; case SyntaxKind . FunctionDeclaration : case SyntaxKind . FunctionExpression : case SyntaxKind . ArrowFunction : return emitFunctionDeclaration ( < FunctionLikeDeclaration > node ) ; case SyntaxKind . DeleteExpression : return emitDeleteExpression ( < DeleteExpression > node ) ; case SyntaxKind . TypeOfExpression : return emitTypeOfExpression ( < TypeOfExpression > node ) ; case SyntaxKind . VoidExpression : return emitVoidExpression ( < VoidExpression > node ) ; case SyntaxKind . PrefixUnaryExpression : return emitPrefixUnaryExpression ( < PrefixUnaryExpression > node ) ; case SyntaxKind . PostfixUnaryExpression : return emitPostfixUnaryExpression ( < PostfixUnaryExpression > node ) ; case SyntaxKind . BinaryExpression : return emitBinaryExpression ( < BinaryExpression > node ) ; case SyntaxKind . ConditionalExpression : return emitConditionalExpression ( < ConditionalExpression > node ) ; case SyntaxKind . OmittedExpression : return ; case SyntaxKind . Block : case SyntaxKind . TryBlock : case SyntaxKind . FinallyBlock : case SyntaxKind . ModuleBlock : return emitBlock ( < Block > node ) ; case SyntaxKind . VariableStatement : return emitVariableStatement ( < VariableStatement > node ) ; case SyntaxKind . EmptyStatement : return write ( ";" ) ; case SyntaxKind . ExpressionStatement : return emitExpressionStatement ( < ExpressionStatement > node ) ; case SyntaxKind . IfStatement : return emitIfStatement ( < IfStatement > node ) ; case SyntaxKind . DoStatement : return emitDoStatement ( < DoStatement > node ) ; case SyntaxKind . WhileStatement : return emitWhileStatement ( < WhileStatement > node ) ; case SyntaxKind . ForStatement : return emitForStatement ( < ForStatement > node ) ; case SyntaxKind . ForInStatement : return emitForInStatement ( < ForInStatement > node ) ; case SyntaxKind . ContinueStatement : case SyntaxKind . BreakStatement : return emitBreakOrContinueStatement ( < BreakOrContinueStatement > node ) ; case SyntaxKind . ReturnStatement : return emitReturnStatement ( < ReturnStatement > node ) ; case SyntaxKind . WithStatement : return emitWithStatement ( < WithStatement > node ) ; case SyntaxKind . SwitchStatement : return emitSwitchStatement ( < SwitchStatement > node ) ; case SyntaxKind . CaseClause : case SyntaxKind . DefaultClause : return emitCaseOrDefaultClause ( < CaseOrDefaultClause > node ) ; case SyntaxKind . LabeledStatement : return emitLabelledStatement ( < LabeledStatement > node ) ; case SyntaxKind . ThrowStatement : return emitThrowStatement ( < ThrowStatement > node ) ; case SyntaxKind . TryStatement : return emitTryStatement ( < TryStatement > node ) ; case SyntaxKind . CatchClause : return emitCatchClause ( < CatchClause > node ) ; case SyntaxKind . DebuggerStatement : return emitDebuggerStatement ( node ) ; case SyntaxKind . VariableDeclaration : return emitVariableDeclaration ( < VariableDeclaration > node ) ; case SyntaxKind . ClassDeclaration : return emitClassDeclaration ( < ClassDeclaration > node ) ; case SyntaxKind . InterfaceDeclaration : return emitInterfaceDeclaration ( < InterfaceDeclaration > node ) ; case SyntaxKind . EnumDeclaration : return emitEnumDeclaration ( < EnumDeclaration > node ) ; case SyntaxKind . ModuleDeclaration : return emitModuleDeclaration ( < ModuleDeclaration > node ) ; case SyntaxKind . ImportDeclaration : return emitImportDeclaration ( < ImportDeclaration > node ) ; case SyntaxKind . SourceFile : return emitSourceFile ( < SourceFile > node ) ; } if ( compilerOptions . target < ScriptTarget . ES6 ) { switch ( node . kind ) { case SyntaxKind . ShorthandPropertyAssignment : return emitDownlevelShorthandPropertyAssignment ( < ShorthandPropertyAssignment > node ) ; case SyntaxKind . Method : return emitDownlevelMethod ( < MethodDeclaration > node ) ; } } else { Debug . assert ( compilerOptions . target >= ScriptTarget . ES6 , "Invalid ScriptTarget. We should emit as ES6 or above" ) ; switch ( node . kind ) { case SyntaxKind . ShorthandPropertyAssignment : return emitShorthandPropertyAssignment ( < ShorthandPropertyAssignment > node ) ; case SyntaxKind . Method : return emitMethod ( < MethodDeclaration > node ) ; } } } function hasDetachedComments ( pos ) { return detachedCommentsInfo !== undefined && detachedCommentsInfo [ detachedCommentsInfo . length - 1 ] . nodePos === pos ; } function getLeadingCommentsWithoutDetachedComments ( ) { var leadingComments = getLeadingCommentRanges ( currentSourceFile . text , detachedCommentsInfo [ detachedCommentsInfo . length - 1 ] . detachedCommentEndPos ) ; if ( detachedCommentsInfo . length - 1 ) { detachedCommentsInfo . pop ( ) ; } else { detachedCommentsInfo = undefined ; } return leadingComments ; } function getLeadingCommentsToEmit ( node ) { if ( node . parent . kind === SyntaxKind . SourceFile || node . pos !== node . parent . pos ) { var leadingComments ; if ( hasDetachedComments ( node . pos ) ) { leadingComments = getLeadingCommentsWithoutDetachedComments ( ) ; } else { leadingComments = getLeadingCommentRangesOfNode ( node , currentSourceFile ) ; } return leadingComments ; } } function emitLeadingDeclarationComments ( node ) { var leadingComments = getLeadingCommentsToEmit ( node ) ; emitNewLineBeforeLeadingComments ( currentSourceFile , writer , node , leadingComments ) ; emitComments ( currentSourceFile , writer , leadingComments , true , newLine , writeComment ) ; } function emitTrailingDeclarationComments ( node ) { if ( node . parent . kind === SyntaxKind . SourceFile || node . end !== node . parent . end ) { var trailingComments = getTrailingCommentRanges ( currentSourceFile . text , node . end ) ; emitComments ( currentSourceFile , writer , trailingComments , false , newLine , writeComment ) ; } } function emitLeadingCommentsOfLocalPosition ( pos ) { var leadingComments ; if ( hasDetachedComments ( pos ) ) { leadingComments = getLeadingCommentsWithoutDetachedComments ( ) ; } else { leadingComments = getLeadingCommentRanges ( currentSourceFile . text , pos ) ; } emitNewLineBeforeLeadingComments ( currentSourceFile , writer , { pos : pos , end : pos } , leadingComments ) ; emitComments ( currentSourceFile , writer , leadingComments , true , newLine , writeComment ) ; } function emitDetachedCommentsAtPosition ( node ) { var leadingComments = getLeadingCommentRanges ( currentSourceFile . text , node . pos ) ; if ( leadingComments ) { var detachedComments = [ ] ; var lastComment ; forEach ( leadingComments , comment => { if ( lastComment ) { var lastCommentLine = getLineOfLocalPosition ( currentSourceFile , lastComment . end ) ; var commentLine = getLineOfLocalPosition ( currentSourceFile , comment . pos ) ; if ( commentLine >= lastCommentLine + 2 ) { return detachedComments ; } } detachedComments . push ( comment ) ; lastComment = comment ; } ) ; if ( detachedComments . length ) { var lastCommentLine = getLineOfLocalPosition ( currentSourceFile , detachedComments [ detachedComments . length - 1 ] . end ) ; var astLine = getLineOfLocalPosition ( currentSourceFile , skipTrivia ( currentSourceFile . text , node . pos ) ) ; if ( astLine >= lastCommentLine + 2 ) { emitNewLineBeforeLeadingComments ( currentSourceFile , writer , node , leadingComments ) ; emitComments ( currentSourceFile , writer , detachedComments , true , newLine , writeComment ) ; var currentDetachedCommentInfo = { nodePos : node . pos , detachedCommentEndPos : detachedComments [ detachedComments . length - 1 ] . end } ; if ( detachedCommentsInfo ) { detachedCommentsInfo . push ( currentDetachedCommentInfo ) ; } else { detachedCommentsInfo = [ currentDetachedCommentInfo ] ; } } } } } function emitPinnedOrTripleSlashCommentsOfNode ( node ) { var pinnedComments = ts . filter ( getLeadingCommentsToEmit ( node ) , isPinnedOrTripleSlashComment ) ; function isPinnedOrTripleSlashComment ( comment ) { if ( currentSourceFile . text . charCodeAt ( comment . pos + 1 ) === CharacterCodes . asterisk ) { return currentSourceFile . text . charCodeAt ( comment . pos + 2 ) === CharacterCodes . exclamation ; } else if ( currentSourceFile . text . charCodeAt ( comment . pos + 1 ) === CharacterCodes . slash && comment . pos + 2 < comment . end && currentSourceFile . text . charCodeAt ( comment . pos + 2 ) === CharacterCodes . slash && currentSourceFile . text . substring ( comment . pos , comment . end ) . match ( fullTripleSlashReferencePathRegEx ) ) { return true ; } } emitNewLineBeforeLeadingComments ( currentSourceFile , writer , node , pinnedComments ) ; emitComments ( currentSourceFile , writer , pinnedComments , true , newLine , writeComment ) ; } if ( compilerOptions . sourceMap ) { initializeEmitterWithSourceMaps ( ) ; } if ( root ) { emit ( root ) ; } else { forEach ( program . getSourceFiles ( ) , sourceFile => { if ( ! isExternalModuleOrDeclarationFile ( sourceFile ) ) { emit ( sourceFile ) ; } } ) ; } writeLine ( ) ; writeEmittedFiles ( writer . getText ( ) , compilerOptions . emitBOM ) ; } function writeDeclarationFile ( jsFilePath , sourceFile ) { var emitDeclarationResult = emitDeclarations ( program , resolver , diagnostics , jsFilePath , sourceFile ) ; if ( ! emitDeclarationResult . reportedDeclarationError ) { var declarationOutput = emitDeclarationResult . referencePathsOutput ; var appliedSyncOutputPos = 0 ; forEach ( emitDeclarationResult . aliasDeclarationEmitInfo , aliasEmitInfo => { if ( aliasEmitInfo . asynchronousOutput ) { declarationOutput += emitDeclarationResult . synchronousDeclarationOutput . substring ( appliedSyncOutputPos , aliasEmitInfo . outputPos ) ; declarationOutput += aliasEmitInfo . asynchronousOutput ; appliedSyncOutputPos = aliasEmitInfo . outputPos ; } } ) ; declarationOutput += emitDeclarationResult . synchronousDeclarationOutput . substring ( appliedSyncOutputPos ) ; writeFile ( compilerHost , diagnostics , removeFileExtension ( jsFilePath ) + ".d.ts" , declarationOutput , compilerOptions . emitBOM ) ; } } var hasSemanticErrors = false ; var isEmitBlocked = false ; if ( targetSourceFile === undefined ) { hasSemanticErrors = resolver . hasSemanticErrors ( ) ; isEmitBlocked = resolver . isEmitBlocked ( ) ; forEach ( program . getSourceFiles ( ) , sourceFile => { if ( shouldEmitToOwnFile ( sourceFile , compilerOptions ) ) { var jsFilePath = getOwnEmitOutputFilePath ( sourceFile , program , ".js" ) ; emitFile ( jsFilePath , sourceFile ) ; } } ) ; if ( compilerOptions . out ) { emitFile ( compilerOptions . out ) ; } } else { if ( shouldEmitToOwnFile ( targetSourceFile , compilerOptions ) ) { hasSemanticErrors = resolver . hasSemanticErrors ( targetSourceFile ) ; isEmitBlocked = resolver . isEmitBlocked ( targetSourceFile ) ; var jsFilePath = getOwnEmitOutputFilePath ( targetSourceFile , program , ".js" ) ; emitFile ( jsFilePath , targetSourceFile ) ; } else if ( ! isDeclarationFile ( targetSourceFile ) && compilerOptions . out ) { forEach ( program . getSourceFiles ( ) , sourceFile => { if ( ! shouldEmitToOwnFile ( sourceFile , compilerOptions ) ) { hasSemanticErrors = hasSemanticErrors || resolver . hasSemanticErrors ( sourceFile ) ; isEmitBlocked = isEmitBlocked || resolver . isEmitBlocked ( sourceFile ) ; } } ) ; emitFile ( compilerOptions . out ) ; } } function emitFile ( jsFilePath , sourceFile ? ) { if ( ! isEmitBlocked ) { emitJavaScript ( jsFilePath , sourceFile ) ; if ( ! hasSemanticErrors && compilerOptions . declaration ) { writeDeclarationFile ( jsFilePath , sourceFile ) ; } } } diagnostics . sort ( compareDiagnostics ) ; diagnostics = deduplicateSortedDiagnostics ( diagnostics ) ; var hasEmitterError = forEach ( diagnostics , diagnostic => diagnostic . category === DiagnosticCategory . Error ) ; var emitResultStatus ; if ( isEmitBlocked ) { emitResultStatus = EmitReturnStatus . AllOutputGenerationSkipped ; } else if ( hasEmitterError ) { emitResultStatus = EmitReturnStatus . EmitErrorsEncountered ; } else if ( hasSemanticErrors && compilerOptions . declaration ) { emitResultStatus = EmitReturnStatus . DeclarationGenerationSkipped ; } else if ( hasSemanticErrors && ! compilerOptions . declaration ) { emitResultStatus = EmitReturnStatus . JSGeneratedWithSemanticErrors ; } else { emitResultStatus = EmitReturnStatus . Succeeded ; } return { emitResultStatus , diagnostics , sourceMaps : sourceMapDataList } ; } }