Cleans up a few things and fixes #7868.

This commit is contained in:
Ron Buckton 2016-04-08 15:31:31 -07:00
parent 381c0260ff
commit 8b506c7b05
8 changed files with 236 additions and 152 deletions

View file

@ -309,7 +309,7 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts
options += " --stripInternal"
}
if (useBuiltCompiler && !/^(no?|f(alse)?|0|-)$/i.test(process.env.USE_TRANSFORMS)) {
if (useBuiltCompiler && !environmentVariableIsDisabled("USE_TRANSFORMS")) {
console.warn("\u001b[93mwarning: 'USE_TRANSFORMS' environment variable is not set to 'false'. Experimental transforms will be enabled by default.\u001b[0m");
}
@ -658,19 +658,21 @@ function exec(cmd, completeHandler, errorHandler) {
}
function cleanTestDirs() {
// Clean the local baselines directory
if (fs.existsSync(localBaseline)) {
jake.rmRf(localBaseline);
}
if (!environmentVariableIsDisabled("CLEAN_TESTS")) {
// Clean the local baselines directory
if (fs.existsSync(localBaseline)) {
jake.rmRf(localBaseline);
}
// Clean the local Rwc baselines directory
if (fs.existsSync(localRwcBaseline)) {
jake.rmRf(localRwcBaseline);
}
// Clean the local Rwc baselines directory
if (fs.existsSync(localRwcBaseline)) {
jake.rmRf(localRwcBaseline);
}
jake.mkdirP(localRwcBaseline);
jake.mkdirP(localTest262Baseline);
jake.mkdirP(localBaseline);
jake.mkdirP(localRwcBaseline);
jake.mkdirP(localTest262Baseline);
jake.mkdirP(localBaseline);
}
}
// used to pass data from jake command line directly to run.js
@ -833,7 +835,7 @@ function runConsoleTests(defaultReporter, defaultSubsets) {
var light = process.env.light || false;
var stackTraceLimit = process.env.stackTraceLimit || 1;
var testConfigFile = 'test.config';
if(fs.existsSync(testConfigFile)) {
if (fs.existsSync(testConfigFile)) {
fs.unlinkSync(testConfigFile);
}
@ -866,7 +868,7 @@ function runConsoleTests(defaultReporter, defaultSubsets) {
console.log(cmd);
exec(cmd, function () {
deleteTemporaryProjectOutput();
if (i === 0) {
if (i === 0 && !environmentVariableIsDisabled("lint")) {
var lint = jake.Task['lint'];
lint.addListener('complete', function () {
complete();
@ -1258,4 +1260,12 @@ ProgressBar.prototype = {
this._lastProgress = progress;
this.visible = true;
}
};
};
function environmentVariableIsEnabled(name) {
return /^(y(es)?|t(rue)?|on|enabled?|1|\+)$/.test(process.env[name]);
}
function environmentVariableIsDisabled(name) {
return /^(no?|f(alse)?|off|disabled?|0|-)$/.test(process.env[name]);
}

View file

@ -1118,7 +1118,7 @@ namespace ts {
}
// Resolves a qualified name and any involved aliases
function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags, ignoreErrors?: boolean): Symbol {
function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags, ignoreErrors?: boolean, location?: Node): Symbol {
if (nodeIsMissing(name)) {
return undefined;
}
@ -1127,7 +1127,7 @@ namespace ts {
if (name.kind === SyntaxKind.Identifier) {
const message = meaning === SymbolFlags.Namespace ? Diagnostics.Cannot_find_namespace_0 : Diagnostics.Cannot_find_name_0;
symbol = resolveName(name, (<Identifier>name).text, meaning, ignoreErrors ? undefined : message, <Identifier>name);
symbol = resolveName(location || name, (<Identifier>name).text, meaning, ignoreErrors ? undefined : message, <Identifier>name);
if (!symbol) {
return undefined;
}
@ -1136,7 +1136,7 @@ namespace ts {
const left = name.kind === SyntaxKind.QualifiedName ? (<QualifiedName>name).left : (<PropertyAccessExpression>name).expression;
const right = name.kind === SyntaxKind.QualifiedName ? (<QualifiedName>name).right : (<PropertyAccessExpression>name).name;
const namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors);
const namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors, location);
if (!namespace || namespace === unknownSymbol || nodeIsMissing(right)) {
return undefined;
}
@ -16042,7 +16042,14 @@ namespace ts {
// Emitter support
function isArgumentsLocalBinding(node: Identifier): boolean {
return getReferencedValueSymbol(node) === argumentsSymbol;
if (!isGeneratedIdentifier(node)) {
node = getSourceTreeNodeOfType(node, isIdentifier);
if (node) {
return getReferencedValueSymbol(node) === argumentsSymbol;
}
}
return false;
}
function moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean {
@ -16077,37 +16084,49 @@ namespace ts {
// When resolved as an expression identifier, if the given node references an exported entity, return the declaration
// node of the exported entity's container. Otherwise, return undefined.
function getReferencedExportContainer(node: Identifier, prefixLocals?: boolean): SourceFile | ModuleDeclaration | EnumDeclaration {
let symbol = getReferencedValueSymbol(node);
if (symbol) {
if (symbol.flags & SymbolFlags.ExportValue) {
// If we reference an exported entity within the same module declaration, then whether
// we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the
// kinds that we do NOT prefix.
const exportSymbol = getMergedSymbol(symbol.exportSymbol);
if (exportSymbol.flags & SymbolFlags.ExportHasLocal && !prefixLocals) {
return undefined;
node = getSourceTreeNodeOfType(node, isIdentifier);
if (node) {
let symbol = getReferencedValueSymbol(node);
if (symbol) {
if (symbol.flags & SymbolFlags.ExportValue) {
// If we reference an exported entity within the same module declaration, then whether
// we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the
// kinds that we do NOT prefix.
const exportSymbol = getMergedSymbol(symbol.exportSymbol);
if (exportSymbol.flags & SymbolFlags.ExportHasLocal && !prefixLocals) {
return undefined;
}
symbol = exportSymbol;
}
symbol = exportSymbol;
}
const parentSymbol = getParentOfSymbol(symbol);
if (parentSymbol) {
if (parentSymbol.flags & SymbolFlags.ValueModule && parentSymbol.valueDeclaration.kind === SyntaxKind.SourceFile) {
return <SourceFile>parentSymbol.valueDeclaration;
}
for (let n = node.parent; n; n = n.parent) {
if ((n.kind === SyntaxKind.ModuleDeclaration || n.kind === SyntaxKind.EnumDeclaration) && getSymbolOfNode(n) === parentSymbol) {
return <ModuleDeclaration | EnumDeclaration>n;
const parentSymbol = getParentOfSymbol(symbol);
if (parentSymbol) {
if (parentSymbol.flags & SymbolFlags.ValueModule && parentSymbol.valueDeclaration.kind === SyntaxKind.SourceFile) {
return <SourceFile>parentSymbol.valueDeclaration;
}
for (let n = node.parent; n; n = n.parent) {
if ((n.kind === SyntaxKind.ModuleDeclaration || n.kind === SyntaxKind.EnumDeclaration) && getSymbolOfNode(n) === parentSymbol) {
return <ModuleDeclaration | EnumDeclaration>n;
}
}
}
}
}
return undefined;
}
// When resolved as an expression identifier, if the given node references an import, return the declaration of
// that import. Otherwise, return undefined.
function getReferencedImportDeclaration(node: Identifier): Declaration {
const symbol = getReferencedValueSymbol(node);
return symbol && symbol.flags & SymbolFlags.Alias ? getDeclarationOfAliasSymbol(symbol) : undefined;
node = getSourceTreeNodeOfType(node, isIdentifier);
if (node) {
const symbol = getReferencedValueSymbol(node);
if (symbol && symbol.flags & SymbolFlags.Alias) {
return getDeclarationOfAliasSymbol(symbol);
}
}
return undefined;
}
function isSymbolOfDeclarationWithCollidingName(symbol: Symbol): boolean {
@ -16157,35 +16176,54 @@ namespace ts {
// a name that either hides an existing name or might hide it when compiled downlevel,
// return the declaration of that entity. Otherwise, return undefined.
function getReferencedDeclarationWithCollidingName(node: Identifier): Declaration {
const symbol = getReferencedValueSymbol(node);
return symbol && isSymbolOfDeclarationWithCollidingName(symbol) ? symbol.valueDeclaration : undefined;
if (!isGeneratedIdentifier(node)) {
node = getSourceTreeNodeOfType(node, isIdentifier);
if (node) {
const symbol = getReferencedValueSymbol(node);
if (symbol && isSymbolOfDeclarationWithCollidingName(symbol)) {
return symbol.valueDeclaration;
}
}
}
return undefined;
}
// Return true if the given node is a declaration of a nested block scoped entity with a name that either hides an
// existing name or might hide a name when compiled downlevel
function isDeclarationWithCollidingName(node: Declaration): boolean {
return isSymbolOfDeclarationWithCollidingName(getSymbolOfNode(node));
node = getSourceTreeNodeOfType(node, isDeclaration);
if (node) {
const symbol = getSymbolOfNode(node);
if (symbol) {
return isSymbolOfDeclarationWithCollidingName(symbol);
}
}
return false;
}
function isValueAliasDeclaration(node: Node): boolean {
node = getSourceTreeNode(node);
switch (node.kind) {
case SyntaxKind.ImportEqualsDeclaration:
case SyntaxKind.ImportClause:
case SyntaxKind.NamespaceImport:
case SyntaxKind.ImportSpecifier:
case SyntaxKind.ExportSpecifier:
return isAliasResolvedToValue(getSymbolOfNode(node));
return isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol);
case SyntaxKind.ExportDeclaration:
const exportClause = (<ExportDeclaration>node).exportClause;
return exportClause && forEach(exportClause.elements, isValueAliasDeclaration);
case SyntaxKind.ExportAssignment:
return (<ExportAssignment>node).expression && (<ExportAssignment>node).expression.kind === SyntaxKind.Identifier ? isAliasResolvedToValue(getSymbolOfNode(node)) : true;
return (<ExportAssignment>node).expression && (<ExportAssignment>node).expression.kind === SyntaxKind.Identifier ? isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol) : true;
}
return false;
}
function isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): boolean {
if (node.parent.kind !== SyntaxKind.SourceFile || !isInternalModuleImportEqualsDeclaration(node)) {
node = getSourceTreeNodeOfType(node, isImportEqualsDeclaration);
if (node === undefined || node.parent.kind !== SyntaxKind.SourceFile || !isInternalModuleImportEqualsDeclaration(node)) {
// parent is not source file or it is not reference to internal module
return false;
}
@ -16212,9 +16250,10 @@ namespace ts {
}
function isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean {
node = getSourceTreeNode(node);
if (isAliasSymbolDeclaration(node)) {
const symbol = getSymbolOfNode(node);
if (getSymbolLinks(symbol).referenced) {
if (symbol && getSymbolLinks(symbol).referenced) {
return true;
}
}
@ -16247,7 +16286,8 @@ namespace ts {
}
function getNodeCheckFlags(node: Node): NodeCheckFlags {
return getNodeLinks(node).flags;
node = getSourceTreeNode(node);
return node ? getNodeLinks(node).flags : undefined;
}
function getEnumMemberValue(node: EnumMember): number {
@ -16275,16 +16315,16 @@ namespace ts {
return type.flags & TypeFlags.ObjectType && getSignaturesOfType(type, SignatureKind.Call).length > 0;
}
function getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind {
function getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind {
// Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true);
const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, location);
const constructorType = valueSymbol ? getTypeOfSymbol(valueSymbol) : undefined;
if (constructorType && isConstructorType(constructorType)) {
return TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue;
}
// Resolve the symbol as a type so that we can provide a more useful hint for the type serializer.
const typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true);
const typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true, location);
// We might not be able to resolve type symbol so use unknown type in that case (eg error case)
if (!typeSymbol) {
return TypeReferenceSerializationKind.ObjectType;
@ -16363,9 +16403,17 @@ namespace ts {
}
function getReferencedValueDeclaration(reference: Identifier): Declaration {
Debug.assert(!nodeIsSynthesized(reference));
const symbol = getReferencedValueSymbol(reference);
return symbol && getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration;
if (!isGeneratedIdentifier(reference)) {
reference = getSourceTreeNodeOfType(reference, isIdentifier);
if (reference) {
const symbol = getReferencedValueSymbol(reference);
if (symbol) {
return getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration;
}
}
}
return undefined;
}
function createResolver(): EmitResolver {

View file

@ -467,7 +467,7 @@ namespace ts {
if (isGeneratedIdentifier(node)) {
return node;
}
if (node.text !== "arguments" && !resolver.isArgumentsLocalBinding(<Identifier>getOriginalNode(node))) {
if (node.text !== "arguments" && !resolver.isArgumentsLocalBinding(node)) {
return node;
}
return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = createUniqueName("arguments"));
@ -1426,10 +1426,7 @@ namespace ts {
// * Why loop initializer is excluded?
// - Since we've introduced a fresh name it already will be undefined.
const original = getOriginalNode(node);
Debug.assert(isVariableDeclaration(original));
const flags = resolver.getNodeCheckFlags(original);
const flags = resolver.getNodeCheckFlags(node);
const isCapturedInFunction = flags & NodeCheckFlags.CapturedBlockScopedBinding;
const isDeclaredInLoop = flags & NodeCheckFlags.BlockScopedBindingInLoop;
const emittedAsTopLevel =
@ -1443,7 +1440,7 @@ namespace ts {
!emittedAsTopLevel
&& enclosingBlockScopeContainer.kind !== SyntaxKind.ForInStatement
&& enclosingBlockScopeContainer.kind !== SyntaxKind.ForOfStatement
&& (!resolver.isDeclarationWithCollidingName(<Declaration>original)
&& (!resolver.isDeclarationWithCollidingName(node)
|| (isDeclaredInLoop
&& !isCapturedInFunction
&& !isIterationStatement(enclosingBlockScopeContainer, /*lookInLabeledStatements*/ false)));
@ -1721,7 +1718,7 @@ namespace ts {
}
function shouldConvertIterationStatementBody(node: IterationStatement): boolean {
return (resolver.getNodeCheckFlags(getOriginalNode(node)) & NodeCheckFlags.LoopWithCapturedBlockScopedBinding) !== 0;
return (resolver.getNodeCheckFlags(node) & NodeCheckFlags.LoopWithCapturedBlockScopedBinding) !== 0;
}
/**
@ -2614,8 +2611,8 @@ namespace ts {
// Only substitute the identifier if we have enabled substitutions for block-scoped
// bindings.
if (enabledSubstitutions & ES6SubstitutionFlags.BlockScopedBindings) {
const original = getOriginalNode(node);
if (isIdentifier(original) && !nodeIsSynthesized(original) && original.parent && isNameOfDeclarationWithCollidingName(original)) {
const original = getSourceTreeNodeOfType(node, isIdentifier);
if (original && isNameOfDeclarationWithCollidingName(original)) {
return getGeneratedNameForNode(original);
}
}
@ -2668,12 +2665,9 @@ namespace ts {
*/
function substituteExpressionIdentifier(node: Identifier): Identifier {
if (enabledSubstitutions & ES6SubstitutionFlags.BlockScopedBindings) {
const original = getOriginalNode(node);
if (isIdentifier(original)) {
const declaration = resolver.getReferencedDeclarationWithCollidingName(original);
if (declaration) {
return getGeneratedNameForNode(declaration.name);
}
const declaration = resolver.getReferencedDeclarationWithCollidingName(node);
if (declaration) {
return getGeneratedNameForNode(declaration.name);
}
}

View file

@ -460,8 +460,7 @@ namespace ts {
function visitExportAssignment(node: ExportAssignment): VisitResult<Statement> {
if (!node.isExportEquals) {
const original = getOriginalNode(node);
if (nodeIsSynthesized(original) || resolver.isValueAliasDeclaration(original)) {
if (nodeIsSynthesized(node) || resolver.isValueAliasDeclaration(node)) {
const statements: Statement[] = [];
addExportDefault(statements, node.expression, /*location*/ node);
return statements;
@ -713,46 +712,43 @@ namespace ts {
}
function substituteExpressionIdentifier(node: Identifier): Expression {
const original = getOriginalNode(node);
if (isIdentifier(original)) {
const container = resolver.getReferencedExportContainer(original, (getNodeEmitFlags(node) & NodeEmitFlags.PrefixExportedLocal) !== 0);
if (container) {
if (container.kind === SyntaxKind.SourceFile) {
return createPropertyAccess(
createIdentifier("exports"),
getSynthesizedClone(node),
/*location*/ node
);
}
const container = resolver.getReferencedExportContainer(node, (getNodeEmitFlags(node) & NodeEmitFlags.ExportName) !== 0);
if (container) {
if (container.kind === SyntaxKind.SourceFile) {
return createPropertyAccess(
createIdentifier("exports"),
getSynthesizedClone(node),
/*location*/ node
);
}
else {
const declaration = resolver.getReferencedImportDeclaration(node.parent ? node : original);
if (declaration) {
if (declaration.kind === SyntaxKind.ImportClause) {
if (languageVersion >= ScriptTarget.ES5) {
return createPropertyAccess(
getGeneratedNameForNode(declaration.parent),
createIdentifier("default"),
/*location*/ node
);
}
else {
return createElementAccess(
getGeneratedNameForNode(declaration.parent),
createLiteral("default"),
/*location*/ node
);
}
}
else if (declaration.kind === SyntaxKind.ImportSpecifier) {
const name = (<ImportSpecifier>declaration).propertyName
|| (<ImportSpecifier>declaration).name;
}
else {
const declaration = resolver.getReferencedImportDeclaration(node);
if (declaration) {
if (declaration.kind === SyntaxKind.ImportClause) {
if (languageVersion >= ScriptTarget.ES5) {
return createPropertyAccess(
getGeneratedNameForNode(declaration.parent.parent.parent),
getSynthesizedClone(name),
getGeneratedNameForNode(declaration.parent),
createIdentifier("default"),
/*location*/ node
);
}
else {
return createElementAccess(
getGeneratedNameForNode(declaration.parent),
createLiteral("default"),
/*location*/ node
);
}
}
else if (declaration.kind === SyntaxKind.ImportSpecifier) {
const name = (<ImportSpecifier>declaration).propertyName
|| (<ImportSpecifier>declaration).name;
return createPropertyAccess(
getGeneratedNameForNode(declaration.parent.parent.parent),
getSynthesizedClone(name),
/*location*/ node
);
}
}
}

View file

@ -570,8 +570,7 @@ namespace ts {
function visitExportAssignment(node: ExportAssignment): Statement {
if (!node.isExportEquals) {
const original = getOriginalNode(node);
if (nodeIsSynthesized(original) || resolver.isValueAliasDeclaration(original)) {
if (nodeIsSynthesized(node) || resolver.isValueAliasDeclaration(node)) {
return createExportStatement(
createLiteral("default"),
node.expression
@ -1012,8 +1011,7 @@ namespace ts {
const left = node.left;
switch (left.kind) {
case SyntaxKind.Identifier:
const originalNode = getOriginalNode(left);
const exportDeclaration = resolver.getReferencedExportContainer(<Identifier>originalNode);
const exportDeclaration = resolver.getReferencedExportContainer(<Identifier>left);
if (exportDeclaration) {
return createExportExpression(<Identifier>left, node);
}

View file

@ -596,7 +596,7 @@ namespace ts {
// Record an alias to avoid class double-binding.
let decoratedClassAlias: Identifier;
if (resolver.getNodeCheckFlags(getOriginalNode(node)) & NodeCheckFlags.DecoratedClassWithSelfReference) {
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.DecoratedClassWithSelfReference) {
enableExpressionSubstitutionForDecoratedClasses();
decoratedClassAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? node.name.text : "default");
decoratedClassAliases[getOriginalNodeId(node)] = decoratedClassAlias;
@ -1380,7 +1380,6 @@ namespace ts {
function addOldTypeMetadata(node: Declaration, decoratorExpressions: Expression[]) {
if (compilerOptions.emitDecoratorMetadata) {
let properties: ObjectLiteralElement[];
if (shouldAddTypeMetadata(node)) {
decoratorExpressions.push(createMetadataHelper("design:type", serializeTypeOfNode(node)));
}
@ -1614,11 +1613,9 @@ namespace ts {
* @param node The type reference node.
*/
function serializeTypeReferenceNode(node: TypeReferenceNode) {
// Clone the type name and parent it to a location outside of the current declaration.
const typeName = cloneEntityName(node.typeName, currentScope);
switch (resolver.getTypeReferenceSerializationKind(typeName)) {
switch (resolver.getTypeReferenceSerializationKind(node.typeName, currentScope)) {
case TypeReferenceSerializationKind.Unknown:
const serialized = serializeEntityNameAsExpression(typeName, /*useFallback*/ true);
const serialized = serializeEntityNameAsExpression(node.typeName, /*useFallback*/ true);
const temp = createTempVariable(hoistVariableDeclaration);
return createLogicalOr(
createLogicalAnd(
@ -1634,7 +1631,7 @@ namespace ts {
);
case TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue:
return serializeEntityNameAsExpression(typeName, /*useFallback*/ false);
return serializeEntityNameAsExpression(node.typeName, /*useFallback*/ false);
case TypeReferenceSerializationKind.VoidType:
return createVoidZero();
@ -1675,17 +1672,20 @@ namespace ts {
function serializeEntityNameAsExpression(node: EntityName, useFallback: boolean): Expression {
switch (node.kind) {
case SyntaxKind.Identifier:
const name = getMutableClone(<Identifier>node);
name.original = undefined;
name.parent = currentScope;
if (useFallback) {
return createLogicalAnd(
createStrictInequality(
createTypeOf(<Identifier>node),
createTypeOf(name),
createLiteral("undefined")
),
<Identifier>node
name
);
}
return <Identifier>node;
return name;
case SyntaxKind.QualifiedName:
return serializeQualifiedNameAsExpression(<QualifiedName>node, useFallback);
@ -2646,7 +2646,7 @@ namespace ts {
else {
// We set the "PrefixExportedLocal" flag to indicate to any module transformer
// downstream that any `exports.` prefix should be added.
setNodeEmitFlags(name, getNodeEmitFlags(name) | NodeEmitFlags.PrefixExportedLocal);
setNodeEmitFlags(name, getNodeEmitFlags(name) | NodeEmitFlags.ExportName);
return name;
}
}
@ -2738,41 +2738,52 @@ namespace ts {
}
function substituteExpressionIdentifier(node: Identifier): Expression {
return trySubstituteDecoratedClassName(node)
|| trySubstituteNamespaceExportedName(node)
|| node;
}
function trySubstituteDecoratedClassName(node: Identifier): Expression {
if (enabledSubstitutions & TypeScriptSubstitutionFlags.DecoratedClasses) {
const original = getOriginalNode(node);
if (isIdentifier(original)) {
if (resolver.getNodeCheckFlags(original) & NodeCheckFlags.SelfReferenceInDecoratedClass) {
// Due to the emit for class decorators, any reference to the class from inside of the class body
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
// behavior of class names in ES6.
const declaration = resolver.getReferencedValueDeclaration(original);
if (declaration) {
const classAlias = currentDecoratedClassAliases[getNodeId(declaration)];
if (classAlias) {
return getRelocatedClone(classAlias, /*location*/ node);
}
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.SelfReferenceInDecoratedClass) {
// Due to the emit for class decorators, any reference to the class from inside of the class body
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
// behavior of class names in ES6.
const declaration = resolver.getReferencedValueDeclaration(node);
if (declaration) {
const classAlias = currentDecoratedClassAliases[getNodeId(declaration)];
if (classAlias) {
return getRelocatedClone(classAlias, /*location*/ node);
}
}
}
}
return undefined;
}
function trySubstituteNamespaceExportedName(node: Identifier): Expression {
if (enabledSubstitutions & applicableSubstitutions) {
// If this is explicitly a local name, do not substitute.
if (getNodeEmitFlags(node) & NodeEmitFlags.LocalName) {
return node;
}
// If we are nested within a namespace declaration, we may need to qualifiy
// an identifier that is exported from a merged namespace.
const original = getOriginalNode(node);
if (isIdentifier(original) && original.parent) {
const container = resolver.getReferencedExportContainer(original);
if (container) {
const substitute =
(applicableSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && container.kind === SyntaxKind.ModuleDeclaration) ||
(applicableSubstitutions & TypeScriptSubstitutionFlags.NonQualifiedEnumMembers && container.kind === SyntaxKind.EnumDeclaration);
if (substitute) {
return createPropertyAccess(getGeneratedNameForNode(container), node, /*location*/ node);
}
const original = getSourceTreeNodeOfType(node, isIdentifier);
const container = resolver.getReferencedExportContainer(original, /*prefixLocals*/ false);
if (container && original !== container.name) {
const substitute =
(applicableSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && container.kind === SyntaxKind.ModuleDeclaration) ||
(applicableSubstitutions & TypeScriptSubstitutionFlags.NonQualifiedEnumMembers && container.kind === SyntaxKind.EnumDeclaration);
if (substitute) {
return createPropertyAccess(getGeneratedNameForNode(container), node, /*location*/ node);
}
}
}
return node;
return undefined;
}
function substituteCallExpression(node: CallExpression): Expression {
@ -2900,7 +2911,7 @@ namespace ts {
function getSuperContainerAsyncMethodFlags() {
return currentSuperContainer !== undefined
&& resolver.getNodeCheckFlags(getOriginalNode(currentSuperContainer)) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding);
&& resolver.getNodeCheckFlags(currentSuperContainer) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding);
}
}
}

View file

@ -1963,7 +1963,7 @@ namespace ts {
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
getReferencedValueDeclaration(reference: Identifier): Declaration;
getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind;
getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind;
isOptionalParameter(node: ParameterDeclaration): boolean;
moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean;
isArgumentsLocalBinding(node: Identifier): boolean;
@ -2875,8 +2875,9 @@ namespace ts {
NoSourceMap = 1 << 10, // Do not emit a source map location for this node.
NoNestedSourceMaps = 1 << 11, // Do not emit source map locations for children of this node.
NoComments = 1 << 12, // Do not emit comments for this node.
PrefixExportedLocal = 1 << 13, // Ensure an export prefix is added for an identifier that points to an exported declaration with a local name (see SymbolFlags.ExportHasLocal).
Indented = 1 << 14, // Adds an explicit extra indentation level for class and function bodies when printing (used to match old emitter).
ExportName = 1 << 13, // Ensure an export prefix is added for an identifier that points to an exported declaration with a local name (see SymbolFlags.ExportHasLocal).
LocalName = 1 << 14, // Ensure an export prefix is not added for an identifier that points to an exported declaration.
Indented = 1 << 15, // Adds an explicit extra indentation level for class and function bodies when printing (used to match old emitter).
}
/** Additional context provided to `visitEachChild` */

View file

@ -1713,16 +1713,20 @@ namespace ts {
/**
* Creates a deep clone of an EntityName, with new parent pointers.
* NOTE: The new entity name will *not* have "original" pointers.
*
* @param node The EntityName to clone.
* @param parent The parent for the cloned node.
*/
export function cloneEntityName(node: EntityName, parent?: Node): EntityName {
const clone = getMutableClone(node);
clone.original = undefined;
clone.parent = parent;
if (isQualifiedName(clone)) {
const { left, right } = clone;
clone.left = cloneEntityName(left, clone);
clone.right = getMutableClone(right);
clone.right.original = undefined;
clone.right.parent = clone;
}
@ -1741,13 +1745,31 @@ namespace ts {
}
export function getOriginalNode(node: Node): Node {
while (node.original !== undefined) {
node = node.original;
if (node) {
while (node.original !== undefined) {
node = node.original;
}
}
return node;
}
export function getSourceTreeNode(node: Node): Node {
node = getOriginalNode(node);
if (node) {
if (node.parent || node.kind === SyntaxKind.SourceFile) {
return node;
}
}
return undefined;
}
export function getSourceTreeNodeOfType<T extends Node>(node: T, nodeTest: (node: Node) => node is T): T {
const source = getSourceTreeNode(node);
return source && nodeTest(source) ? source : undefined;
}
export function getOriginalNodeId(node: Node) {
node = getOriginalNode(node);
return node ? getNodeId(node) : 0;
@ -2999,7 +3021,7 @@ namespace ts {
break;
case SyntaxKind.ImportEqualsDeclaration:
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference && resolver.isReferencedAliasDeclaration(getOriginalNode(node))) {
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference && resolver.isReferencedAliasDeclaration(node)) {
// import x = require("mod") where x is referenced
externalImports.push(<ImportEqualsDeclaration>node);
}
@ -3012,7 +3034,7 @@ namespace ts {
externalImports.push(<ExportDeclaration>node);
hasExportStars = true;
}
else if (resolver.isValueAliasDeclaration(getOriginalNode(node))) {
else if (resolver.isValueAliasDeclaration(node)) {
// export { x, y } from "mod" where at least one export is a value symbol
externalImports.push(<ExportDeclaration>node);
}
@ -3414,6 +3436,10 @@ namespace ts {
|| kind === SyntaxKind.ModuleDeclaration;
}
export function isImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration {
return node.kind === SyntaxKind.ImportEqualsDeclaration;
}
export function isImportClause(node: Node): node is ImportClause {
return node.kind === SyntaxKind.ImportClause;
}