@@ -535,9 +535,14 @@ namespace ts {
535535 let parseErrorBeforeNextFinishedNode = false ;
536536
537537 export function parseSourceFile ( fileName : string , _sourceText : string , languageVersion : ScriptTarget , _syntaxCursor : IncrementalParser . SyntaxCursor , setParentNodes ?: boolean , scriptKind ?: ScriptKind ) : SourceFile {
538+ // Using scriptKind as a condition handles both:
539+ // - 'scriptKind' is unspecified and thus it is `undefined`
540+ // - 'scriptKind' is set and it is `Unknown` (0)
541+ // If the 'scriptKind' is 'undefined' or 'Unknown' then attempt
542+ // to get the ScriptKind from the file name.
543+ scriptKind = scriptKind ? scriptKind : getScriptKindFromFileName ( fileName ) ;
538544
539- const isJavaScriptFile = scriptKind === ScriptKind . JS || hasJavaScriptFileExtension ( fileName ) ;
540- initializeState ( fileName , _sourceText , languageVersion , isJavaScriptFile , _syntaxCursor ) ;
545+ initializeState ( fileName , _sourceText , languageVersion , _syntaxCursor , scriptKind ) ;
541546
542547 const result = parseSourceFileWorker ( fileName , languageVersion , setParentNodes , scriptKind ) ;
543548
@@ -546,12 +551,28 @@ namespace ts {
546551 return result ;
547552 }
548553
549- function getLanguageVariant ( fileName : string ) {
554+ function getScriptKindFromFileName ( fileName : string ) : ScriptKind {
555+ const ext = fileName . split ( "." ) . pop ( ) ;
556+ switch ( ext . toLowerCase ( ) ) {
557+ case "js" :
558+ return ScriptKind . JS ;
559+ case "jsx" :
560+ return ScriptKind . JSX ;
561+ case "ts" :
562+ return ScriptKind . TS ;
563+ case "tsx" :
564+ return ScriptKind . TSX ;
565+ default :
566+ return ScriptKind . TS ;
567+ }
568+ }
569+
570+ function getLanguageVariant ( scriptKind : ScriptKind ) {
550571 // .tsx and .jsx files are treated as jsx language variant.
551- return fileExtensionIs ( fileName , ".tsx" ) || fileExtensionIs ( fileName , ".jsx" ) || fileExtensionIs ( fileName , ".js" ) ? LanguageVariant . JSX : LanguageVariant . Standard ;
572+ return scriptKind === ScriptKind . TSX || scriptKind === ScriptKind . JSX || scriptKind === ScriptKind . JS ? LanguageVariant . JSX : LanguageVariant . Standard ;
552573 }
553574
554- function initializeState ( fileName : string , _sourceText : string , languageVersion : ScriptTarget , isJavaScriptFile : boolean , _syntaxCursor : IncrementalParser . SyntaxCursor ) {
575+ function initializeState ( fileName : string , _sourceText : string , languageVersion : ScriptTarget , _syntaxCursor : IncrementalParser . SyntaxCursor , scriptKind : ScriptKind ) {
555576 NodeConstructor = objectAllocator . getNodeConstructor ( ) ;
556577 SourceFileConstructor = objectAllocator . getSourceFileConstructor ( ) ;
557578
@@ -564,14 +585,14 @@ namespace ts {
564585 identifierCount = 0 ;
565586 nodeCount = 0 ;
566587
567- contextFlags = isJavaScriptFile ? NodeFlags . JavaScriptFile : NodeFlags . None ;
588+ contextFlags = scriptKind === ScriptKind . JS || scriptKind === ScriptKind . JSX ? NodeFlags . JavaScriptFile : NodeFlags . None ;
568589 parseErrorBeforeNextFinishedNode = false ;
569590
570591 // Initialize and prime the scanner before parsing the source elements.
571592 scanner . setText ( sourceText ) ;
572593 scanner . setOnError ( scanError ) ;
573594 scanner . setScriptTarget ( languageVersion ) ;
574- scanner . setLanguageVariant ( getLanguageVariant ( fileName ) ) ;
595+ scanner . setLanguageVariant ( getLanguageVariant ( scriptKind ) ) ;
575596 }
576597
577598 function clearState ( ) {
@@ -587,7 +608,7 @@ namespace ts {
587608 sourceText = undefined ;
588609 }
589610
590- function parseSourceFileWorker ( fileName : string , languageVersion : ScriptTarget , setParentNodes : boolean , scriptKind ? : ScriptKind ) : SourceFile {
611+ function parseSourceFileWorker ( fileName : string , languageVersion : ScriptTarget , setParentNodes : boolean , scriptKind : ScriptKind ) : SourceFile {
591612 sourceFile = createSourceFile ( fileName , languageVersion , scriptKind ) ;
592613 sourceFile . flags = contextFlags ;
593614
@@ -655,7 +676,7 @@ namespace ts {
655676 }
656677 }
657678
658- function createSourceFile ( fileName : string , languageVersion : ScriptTarget , scriptKind ? : ScriptKind ) : SourceFile {
679+ function createSourceFile ( fileName : string , languageVersion : ScriptTarget , scriptKind : ScriptKind ) : SourceFile {
659680 // code from createNode is inlined here so createNode won't have to deal with special case of creating source files
660681 // this is quite rare comparing to other nodes and createNode should be as fast as possible
661682 const sourceFile = < SourceFile > new SourceFileConstructor ( SyntaxKind . SourceFile , /*pos*/ 0 , /* end */ sourceText . length ) ;
@@ -665,11 +686,9 @@ namespace ts {
665686 sourceFile . bindDiagnostics = [ ] ;
666687 sourceFile . languageVersion = languageVersion ;
667688 sourceFile . fileName = normalizePath ( fileName ) ;
668- sourceFile . languageVariant = getLanguageVariant ( sourceFile . fileName ) ;
689+ sourceFile . languageVariant = getLanguageVariant ( scriptKind ) ;
669690 sourceFile . isDeclarationFile = fileExtensionIs ( sourceFile . fileName , ".d.ts" ) ;
670-
671- scriptKind = scriptKind || ScriptKind . Unknown ;
672- sourceFile . scriptKind = scriptKind !== ScriptKind . Unknown ? scriptKind : ScriptKind . TS ;
691+ sourceFile . scriptKind = scriptKind ;
673692
674693 return sourceFile ;
675694 }
@@ -5594,7 +5613,7 @@ namespace ts {
55945613 }
55955614
55965615 export function parseJSDocTypeExpressionForTests ( content : string , start : number , length : number ) {
5597- initializeState ( "file.js" , content , ScriptTarget . Latest , /*isJavaScriptFile*/ true , /* _syntaxCursor:*/ undefined ) ;
5616+ initializeState ( "file.js" , content , ScriptTarget . Latest , /*_syntaxCursor:*/ undefined , ScriptKind . JS ) ;
55985617 scanner . setText ( content , start , length ) ;
55995618 token = scanner . scan ( ) ;
56005619 const jsDocTypeExpression = parseJSDocTypeExpression ( ) ;
@@ -5913,7 +5932,7 @@ namespace ts {
59135932 }
59145933
59155934 export function parseIsolatedJSDocComment ( content : string , start : number , length : number ) {
5916- initializeState ( "file.js" , content , ScriptTarget . Latest , /*isJavaScriptFile*/ true , /* _syntaxCursor:*/ undefined ) ;
5935+ initializeState ( "file.js" , content , ScriptTarget . Latest , /*_syntaxCursor:*/ undefined , ScriptKind . JS ) ;
59175936 sourceFile = < SourceFile > { languageVariant : LanguageVariant . Standard , text : content } ;
59185937 const jsDocComment = parseJSDocCommentWorker ( start , length ) ;
59195938 const diagnostics = parseDiagnostics ;
0 commit comments