diff --git a/src/services/services.ts b/src/services/services.ts index 42f6160bd3e..9edc38be669 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4656,7 +4656,6 @@ module ts { function classifySymbol(symbol: Symbol, meaningAtPosition: SemanticMeaning) { var flags = symbol.getFlags(); - // TODO(drosen): use meaningAtPosition. if (flags & SymbolFlags.Class) { return ClassificationTypeNames.className; } @@ -4672,10 +4671,25 @@ module ts { } } else if (flags & SymbolFlags.Module) { - return ClassificationTypeNames.moduleName; + // Only classify a module as such if + // - It appears in a namespace context. + // - There exists a module declaration which actually impacts the value side. + if (meaningAtPosition & SemanticMeaning.Namespace || + (meaningAtPosition & SemanticMeaning.Value && hasValueSideModule(symbol))) { + return ClassificationTypeNames.moduleName; + } } return undefined; + + /** + * Returns true if there exists a module that introduces entities on the value side. + */ + function hasValueSideModule(symbol: Symbol): boolean { + return !!forEach(symbol.declarations, declaration => { + return declaration.kind === SyntaxKind.ModuleDeclaration && isInstantiated(declaration); + }); + } } function processNode(node: Node) { diff --git a/tests/cases/fourslash/semanticClassification3.ts b/tests/cases/fourslash/semanticClassification3.ts index c1d8da243e7..fb3717006fe 100644 --- a/tests/cases/fourslash/semanticClassification3.ts +++ b/tests/cases/fourslash/semanticClassification3.ts @@ -9,4 +9,4 @@ ////var M = { I: 10 }; var c = classification; -verify.semanticClassificationsAre(c.moduleName("M"), c.interfaceName("I"), c.moduleName("M")); \ No newline at end of file +verify.semanticClassificationsAre(c.moduleName("M"), c.interfaceName("I")); \ No newline at end of file diff --git a/tests/cases/fourslash/semanticClassification4.ts b/tests/cases/fourslash/semanticClassification4.ts new file mode 100644 index 00000000000..295af091e75 --- /dev/null +++ b/tests/cases/fourslash/semanticClassification4.ts @@ -0,0 +1,19 @@ +/// + +////module M { +//// export interface I { +//// } +////} +//// +////var M = { +//// foo: 10, +//// bar: 20 +////} +//// +////var v: M.I; +//// +////var x = M; + +var c = classification; +verify.semanticClassificationsAre( + c.moduleName("M"), c.interfaceName("I"), c.moduleName("M"), c.interfaceName("I")); diff --git a/tests/cases/fourslash/semanticClassification5.ts b/tests/cases/fourslash/semanticClassification5.ts new file mode 100644 index 00000000000..96cce6f4255 --- /dev/null +++ b/tests/cases/fourslash/semanticClassification5.ts @@ -0,0 +1,20 @@ +/// + +////module M { +//// export interface I { +//// } +//// var x = 10; +////} +//// +////var M = { +//// foo: 10, +//// bar: 20 +////} +//// +////var v: M.I; +//// +////var x = M; + +var c = classification; +verify.semanticClassificationsAre( + c.moduleName("M"), c.interfaceName("I"), c.moduleName("M"), c.interfaceName("I"), c.moduleName("M")); diff --git a/tests/cases/fourslash/semanticClassification6.ts b/tests/cases/fourslash/semanticClassification6.ts new file mode 100644 index 00000000000..bcbd5f514f4 --- /dev/null +++ b/tests/cases/fourslash/semanticClassification6.ts @@ -0,0 +1,23 @@ +/// + +////module M { +//// export interface I { +//// } +////} +//// +////module M { +//// var x = 10; +////} +//// +////var M = { +//// foo: 10, +//// bar: 20 +////} +//// +////var v: M.I; +//// +////var x = M; + +var c = classification; +verify.semanticClassificationsAre( + c.moduleName("M"), c.interfaceName("I"), c.moduleName("M"), c.moduleName("M"), c.interfaceName("I"), c.moduleName("M"));