@@ -78,6 +78,7 @@ import {
7878 OperatorKind ,
7979 DecoratorFlags ,
8080 PropertyPrototype ,
81+ IndexSignature ,
8182 File ,
8283 mangleInternalName
8384} from "./program" ;
@@ -578,7 +579,8 @@ export class Compiler extends DiagnosticEmitter {
578579 case ElementKind . ENUM :
579580 case ElementKind . NAMESPACE :
580581 case ElementKind . FILE :
581- case ElementKind . TYPEDEFINITION : break ;
582+ case ElementKind . TYPEDEFINITION :
583+ case ElementKind . INDEXSIGNATURE : break ;
582584
583585 default : assert ( false ) ; // unexpected module export
584586 }
@@ -697,7 +699,8 @@ export class Compiler extends DiagnosticEmitter {
697699 }
698700 case ElementKind . NAMESPACE :
699701 case ElementKind . TYPEDEFINITION :
700- case ElementKind . ENUMVALUE : break ;
702+ case ElementKind . ENUMVALUE :
703+ case ElementKind . INDEXSIGNATURE : break ;
701704 default : assert ( false , ElementKind [ element . kind ] ) ;
702705 }
703706 if ( compileMembers ) this . compileMembers ( element ) ;
@@ -5220,44 +5223,30 @@ export class Compiler extends DiagnosticEmitter {
52205223 if ( setterInstance . hasDecorator ( DecoratorFlags . UNSAFE ) ) this . checkUnsafe ( expression ) ;
52215224 break ;
52225225 }
5223- case ElementKind . CLASS : {
5224- if ( elementExpression ) { // indexed access
5225- let isUnchecked = flow . is ( FlowFlags . UNCHECKED_CONTEXT ) ;
5226- // if (isUnchecked) {
5227- // let arrayType = this.program.determineBuiltinArrayType(<Class>target);
5228- // if (arrayType) {
5229- // return compileBuiltinArraySet(
5230- // this,
5231- // <Class>target,
5232- // assert(this.resolver.currentThisExpression),
5233- // elementExpression,
5234- // valueExpression,
5235- // contextualType
5236- // );
5237- // }
5238- // }
5239- let indexedSet = ( < Class > target ) . lookupOverload ( OperatorKind . INDEXED_SET , isUnchecked ) ;
5240- if ( ! indexedSet ) {
5241- let indexedGet = ( < Class > target ) . lookupOverload ( OperatorKind . INDEXED_GET , isUnchecked ) ;
5242- if ( ! indexedGet ) {
5243- this . error (
5244- DiagnosticCode . Index_signature_is_missing_in_type_0 ,
5245- expression . range , ( < Class > target ) . internalName
5246- ) ;
5247- } else {
5248- this . error (
5249- DiagnosticCode . Index_signature_in_type_0_only_permits_reading ,
5250- expression . range , ( < Class > target ) . internalName
5251- ) ;
5252- }
5253- return this . module . unreachable ( ) ;
5226+ case ElementKind . INDEXSIGNATURE : {
5227+ let parent = ( < IndexSignature > target ) . parent ;
5228+ assert ( parent . kind == ElementKind . CLASS ) ;
5229+ let isUnchecked = flow . is ( FlowFlags . UNCHECKED_CONTEXT ) ;
5230+ let indexedSet = ( < Class > parent ) . lookupOverload ( OperatorKind . INDEXED_SET , isUnchecked ) ;
5231+ if ( ! indexedSet ) {
5232+ let indexedGet = ( < Class > parent ) . lookupOverload ( OperatorKind . INDEXED_GET , isUnchecked ) ;
5233+ if ( ! indexedGet ) {
5234+ this . error (
5235+ DiagnosticCode . Index_signature_is_missing_in_type_0 ,
5236+ expression . range , ( < Class > parent ) . internalName
5237+ ) ;
5238+ } else {
5239+ this . error (
5240+ DiagnosticCode . Index_signature_in_type_0_only_permits_reading ,
5241+ expression . range , ( < Class > parent ) . internalName
5242+ ) ;
52545243 }
5255- assert ( indexedSet . signature . parameterTypes . length == 2 ) ; // parser must guarantee this
5256- targetType = indexedSet . signature . parameterTypes [ 1 ] ; // 2nd parameter is the element
5257- if ( indexedSet . hasDecorator ( DecoratorFlags . UNSAFE ) ) this . checkUnsafe ( expression ) ;
5258- break ;
5244+ return this . module . unreachable ( ) ;
52595245 }
5260- // fall-through
5246+ assert ( indexedSet . signature . parameterTypes . length == 2 ) ; // parser must guarantee this
5247+ targetType = indexedSet . signature . parameterTypes [ 1 ] ; // 2nd parameter is the element
5248+ if ( indexedSet . hasDecorator ( DecoratorFlags . UNSAFE ) ) this . checkUnsafe ( expression ) ;
5249+ break ;
52615250 }
52625251 default : {
52635252 this . error (
@@ -5405,55 +5394,54 @@ export class Compiler extends DiagnosticEmitter {
54055394 ] , valueExpression )
54065395 ] , nativeReturnType ) ;
54075396 }
5408- case ElementKind . CLASS : {
5397+ case ElementKind . INDEXSIGNATURE : {
54095398 if ( this . skippedAutoreleases . has ( valueExpr ) ) valueExpr = this . makeAutorelease ( valueExpr , flow ) ; // (*)
5410- if ( indexExpression ) {
5411- let isUnchecked = flow . is ( FlowFlags . UNCHECKED_CONTEXT ) ;
5412- let indexedGet = ( < Class > target ) . lookupOverload ( OperatorKind . INDEXED_GET , isUnchecked ) ;
5413- if ( ! indexedGet ) {
5414- this . error (
5415- DiagnosticCode . Index_signature_is_missing_in_type_0 ,
5416- valueExpression . range , target . internalName
5417- ) ;
5418- return module . unreachable ( ) ;
5419- }
5420- let indexedSet = ( < Class > target ) . lookupOverload ( OperatorKind . INDEXED_SET , isUnchecked ) ;
5421- if ( ! indexedSet ) {
5422- this . error (
5423- DiagnosticCode . Index_signature_in_type_0_only_permits_reading ,
5424- valueExpression . range , target . internalName
5425- ) ;
5426- this . currentType = tee ? indexedGet . signature . returnType : Type . void ;
5427- return module . unreachable ( ) ;
5428- }
5429- let targetType = ( < Class > target ) . type ;
5430- let thisExpr = this . compileExpression ( assert ( thisExpression ) , this . options . usizeType ) ;
5431- let elementExpr = this . compileExpression ( indexExpression , Type . i32 , Constraints . CONV_IMPLICIT ) ;
5432- if ( tee ) {
5433- let tempLocalTarget = flow . getTempLocal ( targetType ) ;
5434- let tempLocalElement = flow . getAndFreeTempLocal ( this . currentType ) ;
5435- let returnType = indexedGet . signature . returnType ;
5436- flow . freeTempLocal ( tempLocalTarget ) ;
5437- return module . block ( null , [
5438- this . makeCallDirect ( indexedSet , [
5439- module . local_tee ( tempLocalTarget . index , thisExpr ) ,
5440- module . local_tee ( tempLocalElement . index , elementExpr ) ,
5441- valueExpr
5442- ] , valueExpression ) ,
5443- this . makeCallDirect ( indexedGet , [
5444- module . local_get ( tempLocalTarget . index , tempLocalTarget . type . toNativeType ( ) ) ,
5445- module . local_get ( tempLocalElement . index , tempLocalElement . type . toNativeType ( ) )
5446- ] , valueExpression )
5447- ] , returnType . toNativeType ( ) ) ;
5448- } else {
5449- return this . makeCallDirect ( indexedSet , [
5450- thisExpr ,
5451- elementExpr ,
5399+ let isUnchecked = flow . is ( FlowFlags . UNCHECKED_CONTEXT ) ;
5400+ let parent = ( < IndexSignature > target ) . parent ;
5401+ assert ( parent . kind == ElementKind . CLASS ) ;
5402+ let indexedGet = ( < Class > parent ) . lookupOverload ( OperatorKind . INDEXED_GET , isUnchecked ) ;
5403+ if ( ! indexedGet ) {
5404+ this . error (
5405+ DiagnosticCode . Index_signature_is_missing_in_type_0 ,
5406+ valueExpression . range , parent . internalName
5407+ ) ;
5408+ return module . unreachable ( ) ;
5409+ }
5410+ let indexedSet = ( < Class > parent ) . lookupOverload ( OperatorKind . INDEXED_SET , isUnchecked ) ;
5411+ if ( ! indexedSet ) {
5412+ this . error (
5413+ DiagnosticCode . Index_signature_in_type_0_only_permits_reading ,
5414+ valueExpression . range , parent . internalName
5415+ ) ;
5416+ this . currentType = tee ? indexedGet . signature . returnType : Type . void ;
5417+ return module . unreachable ( ) ;
5418+ }
5419+ let targetType = ( < Class > parent ) . type ;
5420+ let thisExpr = this . compileExpression ( assert ( thisExpression ) , this . options . usizeType ) ;
5421+ let elementExpr = this . compileExpression ( assert ( indexExpression ) , Type . i32 , Constraints . CONV_IMPLICIT ) ;
5422+ if ( tee ) {
5423+ let tempLocalTarget = flow . getTempLocal ( targetType ) ;
5424+ let tempLocalElement = flow . getAndFreeTempLocal ( this . currentType ) ;
5425+ let returnType = indexedGet . signature . returnType ;
5426+ flow . freeTempLocal ( tempLocalTarget ) ;
5427+ return module . block ( null , [
5428+ this . makeCallDirect ( indexedSet , [
5429+ module . local_tee ( tempLocalTarget . index , thisExpr ) ,
5430+ module . local_tee ( tempLocalElement . index , elementExpr ) ,
54525431 valueExpr
5453- ] , valueExpression ) ;
5454- }
5432+ ] , valueExpression ) ,
5433+ this . makeCallDirect ( indexedGet , [
5434+ module . local_get ( tempLocalTarget . index , tempLocalTarget . type . toNativeType ( ) ) ,
5435+ module . local_get ( tempLocalElement . index , tempLocalElement . type . toNativeType ( ) )
5436+ ] , valueExpression )
5437+ ] , returnType . toNativeType ( ) ) ;
5438+ } else {
5439+ return this . makeCallDirect ( indexedSet , [
5440+ thisExpr ,
5441+ elementExpr ,
5442+ valueExpr
5443+ ] , valueExpression ) ;
54555444 }
5456- // fall-through
54575445 }
54585446 }
54595447 this . error (
0 commit comments