added folding for references to enum members in enum member initializers, added tests

This commit is contained in:
Vladimir Matveev
2014-10-26 16:40:02 -07:00
parent 97460f5123
commit ce336bcec7
5 changed files with 565 additions and 14 deletions
+24 -11
View File
@@ -7473,18 +7473,31 @@ module ts {
case SyntaxKind.PropertyAccess:
if (!program.getCompilerOptions().propagateEnumConstants) return undefined;
var refSymbol =
e.kind === SyntaxKind.Identifier
? resolveName(member, (<Identifier>e).text, SymbolFlags.EnumMember, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined)
: resolveEntityName(member, e, SymbolFlags.EnumMember, /*suppressErrors*/ true);
var enumSymbol: Symbol;
var propertyName: string;
if (!refSymbol) return undefined;
var refDecl = <EnumMember>refSymbol.valueDeclaration;
// self references are not permitted
// non-qualified names are permitted only to members defined in the same enum
if (member === refDecl || (e.kind === SyntaxKind.Identifier && refDecl.parent !== member.parent)) return undefined;
// enumMemberValue might be undefined if corresponding enum value was not yet computed and it is ok to return undefined in this case
return <number>getNodeLinks(refDecl).enumMemberValue;
if (e.kind === SyntaxKind.Identifier) {
// unqualified names can refer to member that reside in different declaration of the enum so just doing name resolution won't work.
// instead pick symbol that correspond of enum declaration and later try to fetch member from the symbol
enumSymbol = getSymbolOfNode(member.parent);
propertyName = (<Identifier>e).text;
}
else {
// left part in PropertyAccess should be resolved to the symbol of enum that declared 'member'
enumSymbol = resolveEntityName(member, (<PropertyAccess>e).left, SymbolFlags.Enum, /*suppressErrors*/ true);
if (enumSymbol !== getSymbolOfNode(member.parent)) return undefined;
propertyName = (<Identifier>(<PropertyAccess>e).right).text;
}
var propertySymbol = enumSymbol.exports[propertyName];
if (!propertyName || !(propertySymbol.flags & SymbolFlags.EnumMember)) return undefined;
var propertyDecl = <EnumMember>propertySymbol.valueDeclaration;
// self references are illegal
if (member === propertyDecl) return undefined;
// enumMemberValue might be undefined if corresponding enum value was not yet computed
// and it is ok to return undefined in this case (use before defition)
return <number>getNodeLinks(propertyDecl).enumMemberValue;
}
}
}
+4 -3
View File
@@ -749,6 +749,9 @@ module Harness {
case 'usecasesensitivefilenames':
useCaseSensitiveFileNames = setting.value === 'true';
break;
case 'propagateenumconstants':
options.propagateEnumConstants = setting.value === 'true';
break;
case 'mapsourcefiles':
case 'maproot':
@@ -757,7 +760,6 @@ module Harness {
case 'codepage':
case 'createFileLog':
case 'filename':
case 'propagateenumconstants':
case 'removecomments':
case 'watch':
case 'allowautomaticsemicoloninsertion':
@@ -772,7 +774,6 @@ module Harness {
case 'errortruncation':
options.noErrorTruncation = setting.value === 'false';
break;
default:
throw new Error('Unsupported compiler setting ' + setting.flag);
}
@@ -1147,7 +1148,7 @@ module Harness {
var optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*(\S*)/gm; // multiple matches on multiple lines
// List of allowed metadata names
var fileMetadataNames = ["filename", "comments", "declaration", "module", "nolib", "sourcemap", "target", "out", "outdir", "noimplicitany", "noresolve", "newline", "newlines", "emitbom", "errortruncation", "usecasesensitivefilenames"];
var fileMetadataNames = ["filename", "comments", "declaration", "module", "nolib", "sourcemap", "target", "out", "outdir", "noimplicitany", "noresolve", "newline", "newlines", "emitbom", "errortruncation", "usecasesensitivefilenames", "propagateenumconstants"];
function extractCompilerSettings(content: string): CompilerSetting[] {