@@ -92,7 +92,9 @@ module ts {
92
92
getContextualType : getContextualType ,
93
93
getFullyQualifiedName : getFullyQualifiedName ,
94
94
getResolvedSignature : getResolvedSignature ,
95
- getEnumMemberValue : getEnumMemberValue
95
+ getEnumMemberValue : getEnumMemberValue ,
96
+ isValidPropertyAccess : isValidPropertyAccess ,
97
+ getAliasedSymbol : resolveImport
96
98
} ;
97
99
98
100
var undefinedSymbol = createSymbol ( SymbolFlags . Property | SymbolFlags . Transient , "undefined" ) ;
@@ -2573,7 +2575,7 @@ module ts {
2573
2575
function getStringLiteralType ( node : StringLiteralTypeNode ) : StringLiteralType {
2574
2576
if ( hasProperty ( stringLiteralTypes , node . text ) ) return stringLiteralTypes [ node . text ] ;
2575
2577
var type = stringLiteralTypes [ node . text ] = < StringLiteralType > createType ( TypeFlags . StringLiteral ) ;
2576
- type . text = getSourceTextOfNode ( node ) ;
2578
+ type . text = getTextOfNode ( node ) ;
2577
2579
return type ;
2578
2580
}
2579
2581
@@ -4239,6 +4241,25 @@ module ts {
4239
4241
return anyType ;
4240
4242
}
4241
4243
4244
+ function isValidPropertyAccess ( node : PropertyAccess , propertyName : string ) : boolean {
4245
+ var type = checkExpression ( node . left ) ;
4246
+ if ( type !== unknownType && type !== anyType ) {
4247
+ var apparentType = getApparentType ( getWidenedType ( type ) ) ;
4248
+ var prop = getPropertyOfApparentType ( apparentType , propertyName ) ;
4249
+ if ( prop && prop . parent && prop . parent . flags & SymbolFlags . Class ) {
4250
+ if ( node . left . kind === SyntaxKind . SuperKeyword && getDeclarationKindFromSymbol ( prop ) !== SyntaxKind . Method ) {
4251
+ return false ;
4252
+ }
4253
+ else {
4254
+ var diagnosticsCount = diagnostics . length ;
4255
+ checkClassPropertyAccess ( node , type , prop ) ;
4256
+ return diagnostics . length === diagnosticsCount
4257
+ }
4258
+ }
4259
+ }
4260
+ return true ;
4261
+ }
4262
+
4242
4263
function checkIndexedAccess ( node : IndexedAccess ) : Type {
4243
4264
var objectType = checkExpression ( node . object ) ;
4244
4265
var indexType = checkExpression ( node . index ) ;
@@ -4311,25 +4332,32 @@ module ts {
4311
4332
}
4312
4333
4313
4334
function signatureHasCorrectArity ( node : CallExpression , signature : Signature ) : boolean {
4314
- var args = node . arguments || emptyArray ;
4315
- var isCorrect = args . length >= signature . minArgumentCount &&
4316
- ( signature . hasRestParameter || args . length <= signature . parameters . length ) &&
4317
- ( ! node . typeArguments || signature . typeParameters && node . typeArguments . length === signature . typeParameters . length ) ;
4318
-
4319
- // For error recovery, since we have parsed OmittedExpressions for any extra commas
4320
- // in the argument list, if we see any OmittedExpressions, just return true.
4321
- // The reason this is ok is because omitted expressions here are syntactically
4322
- // illegal, and will cause a parse error.
4323
- // Note: It may be worth keeping the upper bound check on arity, but removing
4324
- // the lower bound check if there are omitted expressions.
4325
- if ( ! isCorrect ) {
4326
- // Technically this type assertion is not safe because args could be initialized to emptyArray
4327
- // above.
4328
- if ( ( < NodeArray < Node > > args ) . hasTrailingComma || forEach ( args , arg => arg . kind === SyntaxKind . OmittedExpression ) ) {
4329
- return true ;
4330
- }
4335
+ if ( ! node . arguments ) {
4336
+ // This only happens when we have something of the form:
4337
+ // new C
4338
+ //
4339
+ return signature . minArgumentCount === 0 ;
4340
+ }
4341
+
4342
+ // For IDE scenarios, since we may have an incomplete call, we make two modifications
4343
+ // to arity checking.
4344
+ // 1. A trailing comma is tantamount to adding another argument
4345
+ // 2. If the call is incomplete (no closing paren) allow fewer arguments than expected
4346
+ var args = node . arguments ;
4347
+ var numberOfArgs = args . hasTrailingComma ? args . length + 1 : args . length ;
4348
+ var hasTooManyArguments = ! signature . hasRestParameter && numberOfArgs > signature . parameters . length ;
4349
+ var hasRightNumberOfTypeArguments = ! node . typeArguments ||
4350
+ ( signature . typeParameters && node . typeArguments . length === signature . typeParameters . length ) ;
4351
+
4352
+ if ( hasTooManyArguments || ! hasRightNumberOfTypeArguments ) {
4353
+ return false ;
4331
4354
}
4332
- return isCorrect ;
4355
+
4356
+ // If we are missing the close paren, the call is incomplete, and we should skip
4357
+ // the lower bound check.
4358
+ var callIsIncomplete = args . end === node . end ;
4359
+ var hasEnoughArguments = numberOfArgs >= signature . minArgumentCount ;
4360
+ return callIsIncomplete || hasEnoughArguments ;
4333
4361
}
4334
4362
4335
4363
// If type has a single call signature and no other members, return that signature. Otherwise, return undefined.
@@ -5672,6 +5700,8 @@ module ts {
5672
5700
// when checking exported function declarations across modules check only duplicate implementations
5673
5701
// names and consistency of modifiers are verified when we check local symbol
5674
5702
var isExportSymbolInsideModule = symbol . parent && symbol . parent . flags & SymbolFlags . Module ;
5703
+ var duplicateFunctionDeclaration = false ;
5704
+ var multipleConstructorImplementation = false ;
5675
5705
for ( var i = 0 ; i < declarations . length ; i ++ ) {
5676
5706
var node = < FunctionDeclaration > declarations [ i ] ;
5677
5707
var inAmbientContext = isInAmbientContext ( node ) ;
@@ -5694,10 +5724,10 @@ module ts {
5694
5724
5695
5725
if ( node . body && bodyDeclaration ) {
5696
5726
if ( isConstructor ) {
5697
- error ( node , Diagnostics . Multiple_constructor_implementations_are_not_allowed ) ;
5727
+ multipleConstructorImplementation = true ;
5698
5728
}
5699
5729
else {
5700
- error ( node , Diagnostics . Duplicate_function_implementation ) ;
5730
+ duplicateFunctionDeclaration = true ;
5701
5731
}
5702
5732
}
5703
5733
else if ( ! isExportSymbolInsideModule && previousDeclaration && previousDeclaration . parent === node . parent && previousDeclaration . end !== node . pos ) {
@@ -5721,6 +5751,18 @@ module ts {
5721
5751
}
5722
5752
}
5723
5753
5754
+ if ( multipleConstructorImplementation ) {
5755
+ forEach ( declarations , declaration => {
5756
+ error ( declaration , Diagnostics . Multiple_constructor_implementations_are_not_allowed ) ;
5757
+ } ) ;
5758
+ }
5759
+
5760
+ if ( duplicateFunctionDeclaration ) {
5761
+ forEach ( declarations , declaration => {
5762
+ error ( declaration . name , Diagnostics . Duplicate_function_implementation ) ;
5763
+ } ) ;
5764
+ }
5765
+
5724
5766
if ( ! isExportSymbolInsideModule && lastSeenNonAmbientDeclaration && ! lastSeenNonAmbientDeclaration . body ) {
5725
5767
reportImplementationExpectedError ( lastSeenNonAmbientDeclaration ) ;
5726
5768
}
@@ -7061,23 +7103,6 @@ module ts {
7061
7103
return mapToArray ( symbols ) ;
7062
7104
}
7063
7105
7064
- // True if the given identifier is the name of a type declaration node (class, interface, enum, type parameter, etc)
7065
- function isTypeDeclarationName ( name : Node ) : boolean {
7066
- return name . kind == SyntaxKind . Identifier &&
7067
- isTypeDeclaration ( name . parent ) &&
7068
- ( < Declaration > name . parent ) . name === name ;
7069
- }
7070
-
7071
- function isTypeDeclaration ( node : Node ) : boolean {
7072
- switch ( node . kind ) {
7073
- case SyntaxKind . TypeParameter :
7074
- case SyntaxKind . ClassDeclaration :
7075
- case SyntaxKind . InterfaceDeclaration :
7076
- case SyntaxKind . EnumDeclaration :
7077
- return true ;
7078
- }
7079
- }
7080
-
7081
7106
// True if the given identifier is part of a type reference
7082
7107
function isTypeReferenceIdentifier ( entityName : EntityName ) : boolean {
7083
7108
var node : Node = entityName ;
@@ -7156,75 +7181,6 @@ module ts {
7156
7181
return false ;
7157
7182
}
7158
7183
7159
- function isTypeNode ( node : Node ) : boolean {
7160
- if ( node . kind >= SyntaxKind . FirstTypeNode && node . kind <= SyntaxKind . LastTypeNode ) {
7161
- return true ;
7162
- }
7163
-
7164
- switch ( node . kind ) {
7165
- case SyntaxKind . AnyKeyword :
7166
- case SyntaxKind . NumberKeyword :
7167
- case SyntaxKind . StringKeyword :
7168
- case SyntaxKind . BooleanKeyword :
7169
- return true ;
7170
- case SyntaxKind . VoidKeyword :
7171
- return node . parent . kind !== SyntaxKind . PrefixOperator ;
7172
- case SyntaxKind . StringLiteral :
7173
- // Specialized signatures can have string literals as their parameters' type names
7174
- return node . parent . kind === SyntaxKind . Parameter ;
7175
- // Identifiers and qualified names may be type nodes, depending on their context. Climb
7176
- // above them to find the lowest container
7177
- case SyntaxKind . Identifier :
7178
- // If the identifier is the RHS of a qualified name, then it's a type iff its parent is.
7179
- if ( node . parent . kind === SyntaxKind . QualifiedName ) {
7180
- node = node . parent ;
7181
- }
7182
- // Fall through
7183
- case SyntaxKind . QualifiedName :
7184
- // At this point, node is either a qualified name or an identifier
7185
- var parent = node . parent ;
7186
- if ( parent . kind === SyntaxKind . TypeQuery ) {
7187
- return false ;
7188
- }
7189
- // Do not recursively call isTypeNode on the parent. In the example:
7190
- //
7191
- // var a: A.B.C;
7192
- //
7193
- // Calling isTypeNode would consider the qualified name A.B a type node. Only C or
7194
- // A.B.C is a type node.
7195
- if ( parent . kind >= SyntaxKind . FirstTypeNode && parent . kind <= SyntaxKind . LastTypeNode ) {
7196
- return true ;
7197
- }
7198
- switch ( parent . kind ) {
7199
- case SyntaxKind . TypeParameter :
7200
- return node === ( < TypeParameterDeclaration > parent ) . constraint ;
7201
- case SyntaxKind . Property :
7202
- case SyntaxKind . Parameter :
7203
- case SyntaxKind . VariableDeclaration :
7204
- return node === ( < VariableDeclaration > parent ) . type ;
7205
- case SyntaxKind . FunctionDeclaration :
7206
- case SyntaxKind . FunctionExpression :
7207
- case SyntaxKind . ArrowFunction :
7208
- case SyntaxKind . Constructor :
7209
- case SyntaxKind . Method :
7210
- case SyntaxKind . GetAccessor :
7211
- case SyntaxKind . SetAccessor :
7212
- return node === ( < FunctionDeclaration > parent ) . type ;
7213
- case SyntaxKind . CallSignature :
7214
- case SyntaxKind . ConstructSignature :
7215
- case SyntaxKind . IndexSignature :
7216
- return node === ( < SignatureDeclaration > parent ) . type ;
7217
- case SyntaxKind . TypeAssertion :
7218
- return node === ( < TypeAssertion > parent ) . type ;
7219
- case SyntaxKind . CallExpression :
7220
- case SyntaxKind . NewExpression :
7221
- return ( < CallExpression > parent ) . typeArguments . indexOf ( node ) >= 0 ;
7222
- }
7223
- }
7224
-
7225
- return false ;
7226
- }
7227
-
7228
7184
function isInRightSideOfImportOrExportAssignment ( node : EntityName ) {
7229
7185
while ( node . parent . kind === SyntaxKind . QualifiedName ) {
7230
7186
node = node . parent ;
@@ -7478,7 +7434,7 @@ module ts {
7478
7434
while ( ! isUniqueLocalName ( escapeIdentifier ( prefix + name ) , container ) ) {
7479
7435
prefix += "_" ;
7480
7436
}
7481
- links . localModuleName = prefix + getSourceTextOfNode ( container . name ) ;
7437
+ links . localModuleName = prefix + getTextOfNode ( container . name ) ;
7482
7438
}
7483
7439
return links . localModuleName ;
7484
7440
}
0 commit comments