Add error about missing module flag to createProgram

This commit is contained in:
Jason Freeman 2014-07-17 19:11:01 -07:00
parent f7d7623706
commit 91d31c7f51
5 changed files with 55 additions and 27 deletions

View File

@ -168,7 +168,7 @@ module ts {
declareModuleMember(node, symbolKind, symbolExcludes);
break;
case SyntaxKind.SourceFile:
if (container.flags & NodeFlags.ExternalModule) {
if (isExternalModule(<SourceFile>container)) {
declareModuleMember(node, symbolKind, symbolExcludes);
break;
}
@ -323,7 +323,7 @@ module ts {
bindDeclaration(<Declaration>node, SymbolFlags.Import, SymbolFlags.ImportExcludes);
break;
case SyntaxKind.SourceFile:
if (node.flags & NodeFlags.ExternalModule) {
if (isExternalModule(<SourceFile>node)) {
bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + getModuleNameFromFilename((<SourceFile>node).filename) + '"');
break;
}

View File

@ -183,7 +183,7 @@ module ts {
}
function isGlobalSourceFile(node: Node) {
return node.kind === SyntaxKind.SourceFile && !(node.flags & NodeFlags.ExternalModule);
return node.kind === SyntaxKind.SourceFile && !isExternalModule(<SourceFile>node);
}
function getSymbol(symbols: SymbolTable, name: string, meaning: SymbolFlags): Symbol {
@ -238,7 +238,7 @@ module ts {
}
switch (location.kind) {
case SyntaxKind.SourceFile:
if (!(location.flags & NodeFlags.ExternalModule)) break;
if (!isExternalModule(<SourceFile>location)) break;
case SyntaxKind.ModuleDeclaration:
if (result = getSymbol(getSymbolOfNode(location).exports, name, meaning & SymbolFlags.ModuleMember)) {
return returnResolvedSymbol(result);
@ -610,7 +610,7 @@ module ts {
}
switch (location.kind) {
case SyntaxKind.SourceFile:
if (!(location.flags & NodeFlags.ExternalModule)) {
if (!isExternalModule(<SourceFile>location)) {
break;
}
case SyntaxKind.ModuleDeclaration:
@ -942,7 +942,7 @@ module ts {
}
}
else if (node.kind === SyntaxKind.SourceFile) {
return (node.flags & NodeFlags.ExternalModule) ? node : undefined;
return isExternalModule(<SourceFile>node) ? node : undefined;
}
}
Debug.fail("getContainingModule cant reach here");
@ -5799,7 +5799,7 @@ module ts {
emitExtends = false;
potentialThisCollisions.length = 0;
forEach(node.statements, checkSourceElement);
if (node.flags & NodeFlags.ExternalModule) {
if (isExternalModule(node)) {
var symbol = getExportAssignmentSymbol(node.symbol);
if (symbol && symbol.flags & SymbolFlags.Import) {
// Mark the import as referenced so that we emit it in the final .js file.
@ -5883,7 +5883,7 @@ module ts {
}
switch (location.kind) {
case SyntaxKind.SourceFile:
if (!(location.flags & NodeFlags.ExternalModule)) break;
if (!isExternalModule(<SourceFile>location)) break;
case SyntaxKind.ModuleDeclaration:
copySymbols(getSymbolOfNode(location).exports, meaning & SymbolFlags.ModuleMember);
break;
@ -6036,7 +6036,7 @@ module ts {
return getSourceTextOfNode(node.name);
}
function isExternalModule(symbol: Symbol): boolean {
function isExternalModuleSymbol(symbol: Symbol): boolean {
return symbol.flags & SymbolFlags.ValueModule && symbol.declarations.length === 1 && symbol.declarations[0].kind === SyntaxKind.SourceFile;
}
@ -6057,7 +6057,7 @@ module ts {
// symbol will have a parent if it is an export symbol
if (symbol.parent) {
return isExternalModule(symbol.parent) ? "exports" : symbolToString(symbol.parent);
return isExternalModuleSymbol(symbol.parent) ? "exports" : symbolToString(symbol.parent);
}
}
}
@ -6170,7 +6170,7 @@ module ts {
});
// Initialize global symbol table
forEach(program.getSourceFiles(), file => {
if (!(file.flags & NodeFlags.ExternalModule)) {
if (!isExternalModule(file)) {
extendSymbolTable(globals, file.locals);
}
});

View File

@ -31,7 +31,7 @@ module ts {
function shouldEmitToOwnFile(sourceFile: SourceFile) {
if (!(sourceFile.flags & NodeFlags.DeclarationFile)) {
if ((sourceFile.flags & NodeFlags.ExternalModule || !compilerOptions.out) && !fileExtensionIs(sourceFile.filename, ".js")) {
if ((isExternalModule(sourceFile) || !compilerOptions.out) && !fileExtensionIs(sourceFile.filename, ".js")) {
return true;
}
}
@ -49,7 +49,7 @@ module ts {
}
function isExternalModuleOrDeclarationFile(sourceFile: SourceFile) {
return !!(sourceFile.flags & (NodeFlags.ExternalModule | NodeFlags.DeclarationFile));
return isExternalModule(sourceFile) || (sourceFile.flags & NodeFlags.DeclarationFile) !== 0;
}
function getFirstConstructorWithBody(node: ClassDeclaration): ConstructorDeclaration {
@ -1552,7 +1552,7 @@ module ts {
// preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when
// - current file is not external module
// - import declaration is top level and target is value imported by entity name
emitImportDeclaration = !(currentSourceFile.flags & NodeFlags.ExternalModule) && resolver.isTopLevelValueImportedViaEntityName(node);
emitImportDeclaration = !isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportedViaEntityName(node);
}
if (emitImportDeclaration) {
@ -1701,7 +1701,7 @@ module ts {
write("};");
extendsEmitted = true;
}
if (node.flags & NodeFlags.ExternalModule) {
if (isExternalModule(node)) {
if (compilerOptions.module === ModuleKind.AMD) {
emitAMDModule(node, startIndex);
}

View File

@ -85,6 +85,19 @@ module ts {
return flattenDiagnosticChain(file, start, length, messageChain);
}
export function getErrorSpanForNode(node: Node): TextRange {
var errorSpan: TextRange;
switch (node.kind) {
// This list is a work in progress. Add missing node kinds to improve their error
// spans.
}
return errorSpan && errorSpan.pos < errorSpan.end ? errorSpan : node;
}
export function isExternalModule(file: SourceFile): boolean {
return file.externalModuleIndicator !== undefined;
}
// Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes
// stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise,
// embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns
@ -377,8 +390,9 @@ module ts {
// words, this function is called once we have already parsed the node, and are just
// applying some stricter checks on that node.
function grammarErrorOnNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void {
var start = skipTrivia(file.text, node.pos);
var length = node.end - start;
var span = getErrorSpanForNode(node);
var start = skipTrivia(file.text, span.pos);
var length = span.end - start;
file.syntacticErrors.push(createFileDiagnostic(file, start, length, message, arg0, arg1, arg2));
}
@ -1838,8 +1852,8 @@ module ts {
return makeFunctionExpression(SyntaxKind.FunctionExpression, pos, name, sig, body);
}
function makeFunctionExpression(kind: SyntaxKind, pos: number, name: Identifier, sig: ParsedSignature, body: Node) {
var node = <FunctionDeclaration>createNode(kind, pos);
function makeFunctionExpression(kind: SyntaxKind, pos: number, name: Identifier, sig: ParsedSignature, body: Node): FunctionExpression {
var node = <FunctionExpression>createNode(kind, pos);
node.name = name;
node.typeParameters = sig.typeParameters;
node.parameters = sig.parameters;
@ -2939,10 +2953,13 @@ module ts {
};
}
function isExternalModule() {
return forEach(file.statements, node => node.flags & NodeFlags.Export ||
node.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node).externalModuleName ||
node.kind === SyntaxKind.ExportAssignment ? true : false);
function getExternalModuleIndicator() {
return forEach(file.statements, node =>
node.flags & NodeFlags.Export
|| node.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node).externalModuleName
|| node.kind === SyntaxKind.ExportAssignment
? node
: undefined);
}
scanner = createScanner(languageVersion, sourceText, scanError, onComment);
@ -2961,7 +2978,7 @@ module ts {
file.referencedFiles = referenceComments.referencedFiles;
file.amdDependencies = referenceComments.amdDependencies;
file.statements = parseList(ParsingContext.SourceElements, parseSourceElement);
if (isExternalModule()) file.flags |= NodeFlags.ExternalModule;
file.externalModuleIndicator = getExternalModuleIndicator();
file.nodeCount = nodeCount;
file.identifierCount = identifierCount;
return file;
@ -3130,12 +3147,21 @@ module ts {
return;
}
var firstExternalModule = forEach(files, f => isExternalModule(f) ? f : undefined);
if (firstExternalModule && options.module === ModuleKind.None) {
// We cannot use createDiagnosticFromNode because nodes do not have parents yet
var externalModuleIndicatorNode = firstExternalModule.externalModuleIndicator;
var errorStart = skipTrivia(firstExternalModule.text, externalModuleIndicatorNode.pos);
var errorLength = externalModuleIndicatorNode.end - errorStart;
errors.push(createFileDiagnostic(firstExternalModule, errorStart, errorLength, Diagnostics.Cannot_compile_external_modules_unless_the_module_flag_is_provided));
}
// there has to be common source directory if user specified --outdir || --sourcRoot
// if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted
if (options.outDir || // there is --outDir specified
options.sourceRoot || // there is --sourceRoot specified
(options.mapRoot && // there is --mapRoot Specified and there would be multiple js files generated
(!options.out || !!filter(files, sourceFile => !!(sourceFile.flags & NodeFlags.ExternalModule)).length))) {
(!options.out || firstExternalModule !== undefined))) {
var commonPathComponents: string[];
forEach(files, sourceFile => {

View File

@ -229,7 +229,6 @@ module ts {
MultiLine = 0x00000080, // Multi-line array or object literal
Synthetic = 0x00000100, // Synthetic node (for full fidelity)
DeclarationFile = 0x00000200, // Node is a .d.ts file
ExternalModule = 0x00000400, // Node is an external module
Modifier = Export | Ambient | Public | Private | Static
}
@ -336,7 +335,9 @@ module ts {
whenFalse: Expression;
}
export interface FunctionExpression extends Expression, FunctionDeclaration { }
export interface FunctionExpression extends Expression, FunctionDeclaration {
body: Node; // Required, whereas the member inherited from FunctionDeclaration is optional
}
// The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral
// this means quotes have been removed and escapes have been converted to actual characters. For a NumericLiteral, the
@ -514,6 +515,7 @@ module ts {
syntacticErrors: Diagnostic[];
semanticErrors: Diagnostic[];
hasNoDefaultLib: boolean;
externalModuleIndicator: Node; // The first node that causes this file to be an external module
nodeCount: number;
identifierCount: number;
symbolCount: number;