Input: this function will run after checking the source file so CaptureThis is correct for all nodes [CODESPLIT] function checkIfThisIsCapturedInEnclosingScope ( node ) { var current = node ; while ( current ) { if ( getNodeCheckFlags ( current ) & 4 /* CaptureThis */ ) { var isDeclaration_1 = node . kind !== 69 /* Identifier */ ; if ( isDeclaration_1 ) { error ( node . name , ts . Diagnostics . Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference ) ; } else { error ( node , ts . Diagnostics . Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference ) ; } return ; } current = current . parent ; } }


Input: Check that a parameter initializer contains no references to parameters declared to the right of itself [CODESPLIT] function checkParameterInitializer ( node ) { if ( ts . getRootDeclaration ( node ) . kind !== 138 /* Parameter */ ) { return ; } var func = ts . getContainingFunction ( node ) ; visit ( node . initializer ) ; function visit ( n ) { if ( n . kind === 69 /* Identifier */ ) { var referencedSymbol = getNodeLinks ( n ) . resolvedSymbol ; // check FunctionLikeDeclaration.locals (stores parameters\function local variable) // if it contains entry with a specified name and if this entry matches the resolved symbol if ( referencedSymbol && referencedSymbol !== unknownSymbol && getSymbol ( func . locals , referencedSymbol . name , 107455 /* Value */ ) === referencedSymbol ) { if ( referencedSymbol . valueDeclaration . kind === 138 /* Parameter */ ) { if ( referencedSymbol . valueDeclaration === node ) { error ( n , ts . Diagnostics . Parameter_0_cannot_be_referenced_in_its_initializer , ts . declarationNameToString ( node . name ) ) ; return ; } if ( referencedSymbol . valueDeclaration . pos < node . pos ) { // legal case - parameter initializer references some parameter strictly on left of current parameter declaration return ; } } error ( n , ts . Diagnostics . Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it , ts . declarationNameToString ( node . name ) , ts . declarationNameToString ( n ) ) ; } } else { ts . forEachChild ( n , visit ) ; } } }


Input: Check variable parameter or property declaration [CODESPLIT] function checkVariableLikeDeclaration ( node ) { checkDecorators ( node ) ; checkSourceElement ( node . type ) ; // For a computed property, just check the initializer and exit // Do not use hasDynamicName here, because that returns false for well known symbols. // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. if ( node . name . kind === 136 /* ComputedPropertyName */ ) { checkComputedPropertyName ( node . name ) ; if ( node . initializer ) { checkExpressionCached ( node . initializer ) ; } } // For a binding pattern, check contained binding elements if ( ts . isBindingPattern ( node . name ) ) { ts . forEach ( node . name . elements , checkSourceElement ) ; } // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body if ( node . initializer && ts . getRootDeclaration ( node ) . kind === 138 /* Parameter */ && ts . nodeIsMissing ( ts . getContainingFunction ( node ) . body ) ) { error ( node , ts . Diagnostics . A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation ) ; return ; } // For a binding pattern, validate the initializer and exit if ( ts . isBindingPattern ( node . name ) ) { if ( node . initializer ) { checkTypeAssignableTo ( checkExpressionCached ( node . initializer ) , getWidenedTypeForVariableLikeDeclaration ( node ) , node , /*headMessage*/ undefined ) ; checkParameterInitializer ( node ) ; } return ; } var symbol = getSymbolOfNode ( node ) ; var type = getTypeOfVariableOrParameterOrProperty ( symbol ) ; if ( node === symbol . valueDeclaration ) { // Node is the primary declaration of the symbol, just validate the initializer if ( node . initializer ) { checkTypeAssignableTo ( checkExpressionCached ( node . initializer ) , type , node , /*headMessage*/ undefined ) ; checkParameterInitializer ( node ) ; } } else { // Node is a secondary declaration, check that type is identical to primary declaration and check that // initializer is consistent with type associated with the node var declarationType = getWidenedTypeForVariableLikeDeclaration ( node ) ; if ( type !== unknownType && declarationType !== unknownType && ! isTypeIdenticalTo ( type , declarationType ) ) { error ( node . name , ts . Diagnostics . Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2 , ts . declarationNameToString ( node . name ) , typeToString ( type ) , typeToString ( declarationType ) ) ; } if ( node . initializer ) { checkTypeAssignableTo ( checkExpressionCached ( node . initializer ) , declarationType , node , /*headMessage*/ undefined ) ; } } if ( node . kind !== 141 /* PropertyDeclaration */ && node . kind !== 140 /* PropertySignature */ ) { // We know we don't have a binding pattern or computed name here checkExportsOnMergedDeclarations ( node ) ; if ( node . kind === 211 /* VariableDeclaration */ || node . kind === 163 /* BindingElement */ ) { checkVarDeclaredNamesNotShadowed ( node ) ; } checkCollisionWithCapturedSuperVariable ( node , node . name ) ; checkCollisionWithCapturedThisVariable ( node , node . name ) ; checkCollisionWithRequireExportsInGeneratedCode ( node , node . name ) ; } }


Input: When errorNode is undefined it means we should not report any errors . [CODESPLIT] function checkElementTypeOfIterable ( iterable , errorNode ) { var elementType = getElementTypeOfIterable ( iterable , errorNode ) ; // Now even though we have extracted the iteratedType, we will have to validate that the type // passed in is actually an Iterable. if ( errorNode && elementType ) { checkTypeAssignableTo ( iterable , createIterableType ( elementType ) , errorNode ) ; } return elementType || anyType ; }


Input: Check each type parameter and check that list has no duplicate type parameter declarations [CODESPLIT] function checkTypeParameters ( typeParameterDeclarations ) { if ( typeParameterDeclarations ) { for ( var i = 0 , n = typeParameterDeclarations . length ; i < n ; i ++ ) { var node = typeParameterDeclarations [ i ] ; checkTypeParameter ( node ) ; if ( produceDiagnostics ) { for ( var j = 0 ; j < i ; j ++ ) { if ( typeParameterDeclarations [ j ] . symbol === node . symbol ) { error ( node . name , ts . Diagnostics . Duplicate_identifier_0 , ts . declarationNameToString ( node . name ) ) ; } } } } } }


Input: Function and class expression bodies are checked after all statements in the enclosing body . This is to ensure constructs like the following are permitted : let foo = function () { let s = foo () ; return hello ; } Here performing a full type check of the body of the function expression whilst in the process of determining the type of foo would cause foo to be given type any because of the recursive reference . Delaying the type check of the body ensures foo has been assigned a type . [CODESPLIT] function checkFunctionAndClassExpressionBodies ( node ) { switch ( node . kind ) { case 173 /* FunctionExpression */ : case 174 /* ArrowFunction */ : ts . forEach ( node . parameters , checkFunctionAndClassExpressionBodies ) ; checkFunctionExpressionOrObjectLiteralMethodBody ( node ) ; break ; case 186 /* ClassExpression */ : ts . forEach ( node . members , checkSourceElement ) ; ts . forEachChild ( node , checkFunctionAndClassExpressionBodies ) ; break ; case 143 /* MethodDeclaration */ : case 142 /* MethodSignature */ : ts . forEach ( node . decorators , checkFunctionAndClassExpressionBodies ) ; ts . forEach ( node . parameters , checkFunctionAndClassExpressionBodies ) ; if ( ts . isObjectLiteralMethod ( node ) ) { checkFunctionExpressionOrObjectLiteralMethodBody ( node ) ; } break ; case 144 /* Constructor */ : case 145 /* GetAccessor */ : case 146 /* SetAccessor */ : case 213 /* FunctionDeclaration */ : ts . forEach ( node . parameters , checkFunctionAndClassExpressionBodies ) ; break ; case 205 /* WithStatement */ : checkFunctionAndClassExpressionBodies ( node . expression ) ; break ; case 139 /* Decorator */ : case 138 /* Parameter */ : case 141 /* PropertyDeclaration */ : case 140 /* PropertySignature */ : case 161 /* ObjectBindingPattern */ : case 162 /* ArrayBindingPattern */ : case 163 /* BindingElement */ : case 164 /* ArrayLiteralExpression */ : case 165 /* ObjectLiteralExpression */ : case 245 /* PropertyAssignment */ : case 166 /* PropertyAccessExpression */ : case 167 /* ElementAccessExpression */ : case 168 /* CallExpression */ : case 169 /* NewExpression */ : case 170 /* TaggedTemplateExpression */ : case 183 /* TemplateExpression */ : case 190 /* TemplateSpan */ : case 171 /* TypeAssertionExpression */ : case 189 /* AsExpression */ : case 172 /* ParenthesizedExpression */ : case 176 /* TypeOfExpression */ : case 177 /* VoidExpression */ : case 178 /* AwaitExpression */ : case 175 /* DeleteExpression */ : case 179 /* PrefixUnaryExpression */ : case 180 /* PostfixUnaryExpression */ : case 181 /* BinaryExpression */ : case 182 /* ConditionalExpression */ : case 185 /* SpreadElementExpression */ : case 184 /* YieldExpression */ : case 192 /* Block */ : case 219 /* ModuleBlock */ : case 193 /* VariableStatement */ : case 195 /* ExpressionStatement */ : case 196 /* IfStatement */ : case 197 /* DoStatement */ : case 198 /* WhileStatement */ : case 199 /* ForStatement */ : case 200 /* ForInStatement */ : case 201 /* ForOfStatement */ : case 202 /* ContinueStatement */ : case 203 /* BreakStatement */ : case 204 /* ReturnStatement */ : case 206 /* SwitchStatement */ : case 220 /* CaseBlock */ : case 241 /* CaseClause */ : case 242 /* DefaultClause */ : case 207 /* LabeledStatement */ : case 208 /* ThrowStatement */ : case 209 /* TryStatement */ : case 244 /* CatchClause */ : case 211 /* VariableDeclaration */ : case 212 /* VariableDeclarationList */ : case 214 /* ClassDeclaration */ : case 243 /* HeritageClause */ : case 188 /* ExpressionWithTypeArguments */ : case 217 /* EnumDeclaration */ : case 247 /* EnumMember */ : case 227 /* ExportAssignment */ : case 248 /* SourceFile */ : case 240 /* JsxExpression */ : case 233 /* JsxElement */ : case 234 /* JsxSelfClosingElement */ : case 238 /* JsxAttribute */ : case 239 /* JsxSpreadAttribute */ : case 235 /* JsxOpeningElement */ : ts . forEachChild ( node , checkFunctionAndClassExpressionBodies ) ; break ; } }


Input: Fully type check a source file and collect the relevant diagnostics . [CODESPLIT] function checkSourceFileWorker ( node ) { var links = getNodeLinks ( node ) ; if ( ! ( links . flags & 1 /* TypeChecked */ ) ) { // Check whether the file has declared it is the default lib, // and whether the user has specifically chosen to avoid checking it. if ( node . isDefaultLib && compilerOptions . skipDefaultLibCheck ) { return ; } // Grammar checking checkGrammarSourceFile ( node ) ; emitExtends = false ; emitDecorate = false ; emitParam = false ; potentialThisCollisions . length = 0 ; ts . forEach ( node . statements , checkSourceElement ) ; checkFunctionAndClassExpressionBodies ( node ) ; if ( ts . isExternalModule ( node ) ) { checkExternalModuleExports ( node ) ; } if ( potentialThisCollisions . length ) { ts . forEach ( potentialThisCollisions , checkIfThisIsCapturedInEnclosingScope ) ; potentialThisCollisions . length = 0 ; } if ( emitExtends ) { links . flags |= 8 /* EmitExtends */ ; } if ( emitDecorate ) { links . flags |= 16 /* EmitDecorate */ ; } if ( emitParam ) { links . flags |= 32 /* EmitParam */ ; } if ( emitAwaiter ) { links . flags |= 64 /* EmitAwaiter */ ; } if ( emitGenerator || ( emitAwaiter && languageVersion < 2 /* ES6 */ ) ) { links . flags |= 128 /* EmitGenerator */ ; } links . flags |= 1 /* TypeChecked */ ; } }


Input: Copy the given symbol into symbol tables if the symbol has the given meaning and it doesn t already existed in the symbol table [CODESPLIT] function copySymbol ( symbol , meaning ) { if ( symbol . flags & meaning ) { var id = symbol . name ; // We will copy all symbol regardless of its reserved name because // symbolsToArray will check whether the key is a reserved name and // it will not copy symbol with reserved name to the array if ( ! ts . hasProperty ( symbols , id ) ) { symbols [ id ] = symbol ; } } }


Input: Gets either the static or instance type of a class element based on whether the element is declared as static . [CODESPLIT] function getParentTypeOfClassElement ( node ) { var classSymbol = getSymbolOfNode ( node . parent ) ; return node . flags & 128 /* Static */ ? getTypeOfSymbol ( classSymbol ) : getDeclaredTypeOfSymbol ( classSymbol ) ; }


Input: Return the list of properties of the given type augmented with properties from Function if the type has call or construct signatures [CODESPLIT] function getAugmentedPropertiesOfType ( type ) { type = getApparentType ( type ) ; var propsByName = createSymbolTable ( getPropertiesOfType ( type ) ) ; if ( getSignaturesOfType ( type , 0 /* Call */ ) . length || getSignaturesOfType ( type , 1 /* Construct */ ) . length ) { ts . forEach ( getPropertiesOfType ( globalFunctionType ) , function ( p ) { if ( ! ts . hasProperty ( propsByName , p . name ) ) { propsByName [ p . name ] = p ; } } ) ; } return getNamedMembers ( propsByName ) ; }


Input: Emitter support When resolved as an expression identifier if the given node references an exported entity return the declaration node of the exported entity s container . Otherwise return undefined . [CODESPLIT] function getReferencedExportContainer ( node ) { var symbol = getReferencedValueSymbol ( node ) ; if ( symbol ) { if ( symbol . flags & 1048576 /* ExportValue */ ) { // If we reference an exported entity within the same module declaration, then whether // we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the // kinds that we do NOT prefix. var exportSymbol = getMergedSymbol ( symbol . exportSymbol ) ; if ( exportSymbol . flags & 944 /* ExportHasLocal */ ) { return undefined ; } symbol = exportSymbol ; } var parentSymbol = getParentOfSymbol ( symbol ) ; if ( parentSymbol ) { if ( parentSymbol . flags & 512 /* ValueModule */ && parentSymbol . valueDeclaration . kind === 248 /* SourceFile */ ) { return parentSymbol . valueDeclaration ; } for ( var n = node . parent ; n ; n = n . parent ) { if ( ( n . kind === 218 /* ModuleDeclaration */ || n . kind === 217 /* EnumDeclaration */ ) && getSymbolOfNode ( n ) === parentSymbol ) { return n ; } } } } }


Input: When resolved as an expression identifier if the given node references an import return the declaration of that import . Otherwise return undefined . [CODESPLIT] function getReferencedImportDeclaration ( node ) { var symbol = getReferencedValueSymbol ( node ) ; return symbol && symbol . flags & 8388608 /* Alias */ ? getDeclarationOfAliasSymbol ( symbol ) : undefined ; }


Input: When resolved as an expression identifier if the given node references a nested block scoped entity with a name that hides an existing name return the declaration of that entity . Otherwise return undefined . [CODESPLIT] function getReferencedNestedRedeclaration ( node ) { var symbol = getReferencedValueSymbol ( node ) ; return symbol && isNestedRedeclarationSymbol ( symbol ) ? symbol . valueDeclaration : undefined ; }


Input: GRAMMAR CHECKING [CODESPLIT] function checkGrammarDecorators ( node ) { if ( ! node . decorators ) { return false ; } if ( ! ts . nodeCanBeDecorated ( node ) ) { return grammarErrorOnFirstToken ( node , ts . Diagnostics . Decorators_are_not_valid_here ) ; } else if ( node . kind === 145 /* GetAccessor */ || node . kind === 146 /* SetAccessor */ ) { var accessors = ts . getAllAccessorDeclarations ( node . parent . members , node ) ; if ( accessors . firstAccessor . decorators && node === accessors . secondAccessor ) { return grammarErrorOnFirstToken ( node , ts . Diagnostics . Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name ) ; } } return false ; }


Input: Return a temp variable name to be used in export default statements . The temp name will be of the form _default_counter . Note that export default is only allowed at most once in a module so we do not need to keep track of created temp names . [CODESPLIT] function getExportDefaultTempVariableName ( ) { var baseName = "_default" ; if ( ! ts . hasProperty ( currentSourceFile . identifiers , baseName ) ) { return baseName ; } var count = 0 ; while ( true ) { var name_18 = baseName + "_" + ( ++ count ) ; if ( ! ts . hasProperty ( currentSourceFile . identifiers , name_18 ) ) { return name_18 ; } } }


Input: / * [CODESPLIT] function writeDeclarationFile ( jsFilePath , sourceFile , host , resolver , diagnostics ) { var emitDeclarationResult = emitDeclarations ( host , resolver , diagnostics , jsFilePath , sourceFile ) ; // TODO(shkamat): Should we not write any declaration file if any of them can produce error, // or should we just not write this file like we are doing now if ( ! emitDeclarationResult . reportedDeclarationError ) { var declarationOutput = emitDeclarationResult . referencePathsOutput + getDeclarationOutput ( emitDeclarationResult . synchronousDeclarationOutput , emitDeclarationResult . moduleElementDeclarationEmitInfo ) ; ts . writeFile ( host , diagnostics , ts . removeFileExtension ( jsFilePath ) + ".d.ts" , declarationOutput , host . getCompilerOptions ( ) . emitBOM ) ; } function getDeclarationOutput ( synchronousDeclarationOutput , moduleElementDeclarationEmitInfo ) { var appliedSyncOutputPos = 0 ; var declarationOutput = "" ; // apply asynchronous additions to the synchronous output ts . forEach ( moduleElementDeclarationEmitInfo , function ( aliasEmitInfo ) { if ( aliasEmitInfo . asynchronousOutput ) { declarationOutput += synchronousDeclarationOutput . substring ( appliedSyncOutputPos , aliasEmitInfo . outputPos ) ; declarationOutput += getDeclarationOutput ( aliasEmitInfo . asynchronousOutput , aliasEmitInfo . subModuleElementDeclarationEmitInfo ) ; appliedSyncOutputPos = aliasEmitInfo . outputPos ; } } ) ; declarationOutput += synchronousDeclarationOutput . substring ( appliedSyncOutputPos ) ; return declarationOutput ; } }