@@ -85,6 +85,19 @@ module ts {
8585 return flattenDiagnosticChain ( file , start , length , messageChain ) ;
8686 }
8787
88+ export function getErrorSpanForNode ( node : Node ) : TextRange {
89+ var errorSpan : TextRange ;
90+ switch ( node . kind ) {
91+ // This list is a work in progress. Add missing node kinds to improve their error
92+ // spans.
93+ }
94+ return errorSpan && errorSpan . pos < errorSpan . end ? errorSpan : node ;
95+ }
96+
97+ export function isExternalModule ( file : SourceFile ) : boolean {
98+ return file . externalModuleIndicator !== undefined ;
99+ }
100+
88101 // Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes
89102 // stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise,
90103 // embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns
@@ -377,8 +390,9 @@ module ts {
377390 // words, this function is called once we have already parsed the node, and are just
378391 // applying some stricter checks on that node.
379392 function grammarErrorOnNode ( node : Node , message : DiagnosticMessage , arg0 ?: any , arg1 ?: any , arg2 ?: any ) : void {
380- var start = skipTrivia ( file . text , node . pos ) ;
381- var length = node . end - start ;
393+ var span = getErrorSpanForNode ( node ) ;
394+ var start = skipTrivia ( file . text , span . pos ) ;
395+ var length = span . end - start ;
382396
383397 file . syntacticErrors . push ( createFileDiagnostic ( file , start , length , message , arg0 , arg1 , arg2 ) ) ;
384398 }
@@ -1838,8 +1852,8 @@ module ts {
18381852 return makeFunctionExpression ( SyntaxKind . FunctionExpression , pos , name , sig , body ) ;
18391853 }
18401854
1841- function makeFunctionExpression ( kind : SyntaxKind , pos : number , name : Identifier , sig : ParsedSignature , body : Node ) {
1842- var node = < FunctionDeclaration > createNode ( kind , pos ) ;
1855+ function makeFunctionExpression ( kind : SyntaxKind , pos : number , name : Identifier , sig : ParsedSignature , body : Node ) : FunctionExpression {
1856+ var node = < FunctionExpression > createNode ( kind , pos ) ;
18431857 node . name = name ;
18441858 node . typeParameters = sig . typeParameters ;
18451859 node . parameters = sig . parameters ;
@@ -2939,10 +2953,13 @@ module ts {
29392953 } ;
29402954 }
29412955
2942- function isExternalModule ( ) {
2943- return forEach ( file . statements , node => node . flags & NodeFlags . Export ||
2944- node . kind === SyntaxKind . ImportDeclaration && ( < ImportDeclaration > node ) . externalModuleName ||
2945- node . kind === SyntaxKind . ExportAssignment ? true : false ) ;
2956+ function getExternalModuleIndicator ( ) {
2957+ return forEach ( file . statements , node =>
2958+ node . flags & NodeFlags . Export
2959+ || node . kind === SyntaxKind . ImportDeclaration && ( < ImportDeclaration > node ) . externalModuleName
2960+ || node . kind === SyntaxKind . ExportAssignment
2961+ ? node
2962+ : undefined ) ;
29462963 }
29472964
29482965 scanner = createScanner ( languageVersion , sourceText , scanError , onComment ) ;
@@ -2961,7 +2978,7 @@ module ts {
29612978 file . referencedFiles = referenceComments . referencedFiles ;
29622979 file . amdDependencies = referenceComments . amdDependencies ;
29632980 file . statements = parseList ( ParsingContext . SourceElements , parseSourceElement ) ;
2964- if ( isExternalModule ( ) ) file . flags |= NodeFlags . ExternalModule ;
2981+ file . externalModuleIndicator = getExternalModuleIndicator ( ) ;
29652982 file . nodeCount = nodeCount ;
29662983 file . identifierCount = identifierCount ;
29672984 return file ;
@@ -3130,12 +3147,21 @@ module ts {
31303147 return ;
31313148 }
31323149
3150+ var firstExternalModule = forEach ( files , f => isExternalModule ( f ) ? f : undefined ) ;
3151+ if ( firstExternalModule && options . module === ModuleKind . None ) {
3152+ // We cannot use createDiagnosticFromNode because nodes do not have parents yet
3153+ var externalModuleIndicatorNode = firstExternalModule . externalModuleIndicator ;
3154+ var errorStart = skipTrivia ( firstExternalModule . text , externalModuleIndicatorNode . pos ) ;
3155+ var errorLength = externalModuleIndicatorNode . end - errorStart ;
3156+ errors . push ( createFileDiagnostic ( firstExternalModule , errorStart , errorLength , Diagnostics . Cannot_compile_external_modules_unless_the_module_flag_is_provided ) ) ;
3157+ }
3158+
31333159 // there has to be common source directory if user specified --outdir || --sourcRoot
31343160 // if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted
31353161 if ( options . outDir || // there is --outDir specified
31363162 options . sourceRoot || // there is --sourceRoot specified
31373163 ( options . mapRoot && // there is --mapRoot Specified and there would be multiple js files generated
3138- ( ! options . out || ! ! filter ( files , sourceFile => ! ! ( sourceFile . flags & NodeFlags . ExternalModule ) ) . length ) ) ) {
3164+ ( ! options . out || firstExternalModule !== undefined ) ) ) {
31393165
31403166 var commonPathComponents : string [ ] ;
31413167 forEach ( files , sourceFile => {
0 commit comments