1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008, 2010, 2014 Henrik Tidefelt
19 #include "Shapes_Helpers_decls.h"
22 #include "shapesexceptions.h"
23 #include "classexceptions.h"
27 #include "shapescore.h"
32 using namespace Shapes
;
35 Ast::MethodIdExpr::MethodIdExpr( const Ast::SourceLocation
& loc
, Ast::Expression
* classPart
, const char * name
)
36 : loc_( loc
, bool( ) ), classPart_( classPart
), name_( name
)
39 Ast::MethodIdExpr::~MethodIdExpr( )
43 // Ast::MethodIdExpr::identifier( Kernel::Environment::VariableHandle dstgroup, SimplePDF::PDF_out * pdfo, Kernel::GraphicsState * metaState, Kernel::PassedEnv env ) const
45 // RefCountPtr< const Lang::Value > untypedClass = classPart->value( dstgroup, pdfo, metaState, env );
46 // typedef const Lang::Class ArgType;
47 // RefCountPtr< ArgType > typedClass = untypedClass.down_cast< ArgType >( );
48 // if( typedClass == NullPtr< ArgType >( ) )
50 // throw Exceptions::TypeMismatch( classPart, untypedClass->getTypeName( ), ArgType::staticTypeName( ) );
52 // return Kernel::MethodId( typedClass, id->identifier( dstgroup, pdfo, metaState, env ) );
57 Ast::MemberDeclaration::MemberDeclaration( const Ast::SourceLocation
& loc
, const char * id
, Ast::Expression
* init
, const Ast::MemberMode
& mode
)
58 : loc_( loc
, bool( ) ), id_( id
), init_( init
), mode_( mode
)
60 checkModeConsistency( );
63 Ast::MemberDeclaration::~MemberDeclaration( )
69 Ast::MemberDeclaration::addModeBits( const Ast::MemberMode
& bits
)
72 checkModeConsistency( );
76 Ast::MemberDeclaration::checkModeConsistency( )
78 if( ( mode_
& Ast::MEMBER_CONST
) != 0 && ( mode_
& ( Ast::MEMBER_ACCESS_PUBLIC_INSERT
| Ast::MEMBER_ACCESS_PROTECTED_INSERT
) ) != 0 )
80 throw Exceptions::ParserError( loc_
, strrefdup( "The member cannot be declared both const and assignable." ) );
85 Ast::ClassSection::ClassSection( )
88 Ast::ClassSection::~ClassSection( )
92 Ast::MemberSection::MemberSection( )
95 Ast::MemberSection::~MemberSection( )
97 /* We must not delete the declarations here. This class is only used to pass these declarations on to a ClassExpression, which will be responsible for deletion.
102 Ast::MemberSection::addModeBits( const Ast::MemberMode
& bits
)
104 for( iterator i
= begin( ); i
!= end( ); ++i
)
106 (*i
)->addModeBits( bits
);
111 Ast::PrepareSection::PrepareSection( const Ast::SourceLocation
& loc
, std::list
< Ast::Node
* > * nodes
)
112 : loc_( loc
, bool( ) ), nodes_( nodes
)
115 Ast::PrepareSection::~PrepareSection( )
117 /* We must not delete the expressions here. This class is only used to pass these expressions on to a ClassExpression, which will be responsible for deletion.
118 * However, the list shall be deleted.
124 Ast::AbstractSection::AbstractSection( const Ast::SourceLocation
& loc
, const std::list
< RefCountPtr
< const char > > * methods
)
125 : loc_( loc
, bool( ) ), methods_( methods
)
128 Ast::AbstractSection::~AbstractSection( )
134 Ast::OverridesSection::OverridesSection( Ast::Expression
* super
, Ast::MemberSection
* members
)
135 : super_( super
), members_( members
)
138 Ast::OverridesSection::~OverridesSection( )
145 Ast::ClassFunction::ClassFunction( const Ast::SourceLocation
& loc
, Ast::Expression
* name
, const Kernel::Formals
* constructorFormals
, std::list
< const Ast::CallExpr
* > * parentsWithInitArgs
, Ast::MemberMode classMode
, std::list
< Ast::ClassSection
* > * sections
)
146 : Lang::Function( new Kernel::EvaluatedFormals( Ast::FileID::build_internal( "< class construction >" ), true ) ), loc_( loc
, bool( ) ), name_( name
), constructorFormals_( constructorFormals
), parentsWithInitArgs_( parentsWithInitArgs
), isAbstract_( ( classMode
& Ast::CLASS_MODE_ABSTRACT
) != 0 ), isFinal_( ( classMode
& Ast::CLASS_MODE_FINAL
) != 0 )
148 for( std::list
< Ast::ClassSection
* >::iterator i
= sections
->begin( ); i
!= sections
->end( ); ++i
)
151 typedef Ast::MemberSection T
;
152 T
* memberSection
= dynamic_cast< T
* >( *i
);
153 if( memberSection
!= 0 )
155 for( std::list
< Ast::MemberDeclaration
* >::iterator j
= memberSection
->begin( );
156 j
!= memberSection
->end( );
159 members_
.push_back( *j
);
166 typedef Ast::PrepareSection T
;
167 T
* prepareSection
= dynamic_cast< T
* >( *i
);
168 if( prepareSection
!= 0 )
170 for( std::list
< Ast::Node
* >::iterator j
= prepareSection
->nodes_
->begin( );
171 j
!= prepareSection
->nodes_
->end( );
174 preparations_
.push_back( *j
);
181 typedef Ast::OverridesSection T
;
182 T
* overridesSection
= dynamic_cast< T
* >( *i
);
183 if( overridesSection
!= 0 )
185 overrides_
.push_back( overridesSection
);
190 typedef Ast::AbstractSection T
;
191 T
* abstractSection
= dynamic_cast< T
* >( *i
);
192 if( abstractSection
!= 0 )
194 for( std::list
< RefCountPtr
< const char > >::const_iterator j
= abstractSection
->methods_
->begin( );
195 j
!= abstractSection
->methods_
->end( );
198 abstractSet_
.insert( strdup( j
->getPtr( ) ) );
203 throw Exceptions::InternalError( strrefdup( "ClassFunction::ClassFunction: the ClassSection was neither of the expected types" ) );
208 typedef std::map
< const char *, Ast::MemberDeclaration
*, charPtrLess
> MapType
;
210 for( std::list
< Ast::MemberDeclaration
* >::const_iterator i
= members_
.begin( ); i
!= members_
.end( ); ++i
)
213 if( abstractSet_
.find( (*i
)->id_
) != abstractSet_
.end( ) )
215 throw Exceptions::MemberAlsoAbstract( (*i
)->loc_
, (*i
)->id_
, Ast::THE_UNKNOWN_LOCATION
);
217 MapType::const_iterator j
= seen
.find( (*i
)->id_
);
218 if( j
!= seen
.end( ) )
220 throw Exceptions::MemberAlreadyDeclared( (*i
)->loc_
, (*i
)->id_
, j
->second
->loc_
);
222 seen
[ (*i
)->id_
] = *i
;
224 if( ( (*i
)->mode_
& Ast::MEMBER_ACCESS_PUBLIC_GET
) != 0 )
226 if( ( (*i
)->mode_
& Ast::MEMBER_METHOD
) == 0 && ! isFinal_
)
228 throw Exceptions::PublicGetSetInNonfinalClass( (*i
)->loc_
, (*i
)->id_
);
230 publicGetSet_
.insert( (*i
)->id_
);
232 if( ( (*i
)->mode_
& Ast::MEMBER_ACCESS_PROTECTED_GET
) != 0 )
234 protectedGetSet_
.insert( (*i
)->id_
);
236 if( ( (*i
)->mode_
& Ast::MEMBER_ACCESS_PUBLIC_INSERT
) != 0 )
238 if( ( (*i
)->mode_
& Ast::MEMBER_METHOD
) == 0 && ! isFinal_
)
240 throw Exceptions::PublicGetSetInNonfinalClass( (*i
)->loc_
, (*i
)->id_
);
242 publicSetSet_
.insert( (*i
)->id_
);
244 if( ( (*i
)->mode_
& Ast::MEMBER_ACCESS_PROTECTED_INSERT
) != 0 )
246 protectedSetSet_
.insert( (*i
)->id_
);
248 if( ( (*i
)->mode_
& Ast::MEMBER_FINAL
) != 0 )
250 finalSet_
.insert( (*i
)->id_
);
252 if( ( (*i
)->mode_
& Ast::MEMBER_TRANSFORMING
) != 0 )
254 if( ( (*i
)->mode_
& Ast::MEMBER_METHOD
) == 0 && ! isFinal_
)
256 throw Exceptions::TransformingMemberInNonfinalClass( (*i
)->loc_
, (*i
)->id_
);
258 transformingSet_
.insert( (*i
)->id_
);
264 Ast::ClassFunction::~ClassFunction( )
268 delete constructorFormals_
;
270 for( std::list
< const Ast::CallExpr
* >::iterator i
= parentsWithInitArgs_
->begin( );
271 i
!= parentsWithInitArgs_
->end( );
276 delete parentsWithInitArgs_
;
278 /* preparations_ and members_ delete their elements by themselves
284 Ast::ClassFunction::push_exprs( Ast::ArgListExprs
* args
) const
286 args
->orderedExprs_
->push_back( name_
);
288 constructorFormals_
->push_exprs( args
);
290 typedef std::list
< std::pair
< RefCountPtr
< const Lang::Class
>, const Ast::ArgListExprs
* > > ParentClassList
;
291 RefCountPtr
< ParentClassList
> parents
= RefCountPtr
< ParentClassList
>( new ParentClassList
);
292 for( std::list
< const Ast::CallExpr
* >::iterator i
= parentsWithInitArgs_
->begin( );
293 i
!= parentsWithInitArgs_
->end( );
296 args
->orderedExprs_
->push_back( (*i
)->funExpr_
);
300 typedef std::map
< RefCountPtr
< const Lang::Class
>, std::map
< const char *, Ast::MemberDeclaration
*, charPtrLess
> > MapType
;
303 typedef typeof overrides_ ListType
;
304 for( ListType::const_iterator i
= overrides_
.begin( ); i
!= overrides_
.end( ); ++i
)
306 args
->orderedExprs_
->push_back( (*i
)->super_
);
313 Ast::ClassFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
316 RefCountPtr
< const Lang::String
> typedName
= args
.getHandle( pos
)->getVal
< const Lang::String
>( name_
->loc( ) );
319 Kernel::EvaluatedFormals
* evaluatedFormals
= constructorFormals_
->newEvaluatedFormals( args
, & pos
);
321 typedef std::list
< std::pair
< RefCountPtr
< const Lang::Class
>, const Ast::ArgListExprs
* > > ParentClassList
;
322 RefCountPtr
< ParentClassList
> parents
= RefCountPtr
< ParentClassList
>( new ParentClassList
);
323 for( std::list
< const Ast::CallExpr
* >::iterator i
= parentsWithInitArgs_
->begin( );
324 i
!= parentsWithInitArgs_
->end( );
327 RefCountPtr
< const Lang::Class
> typedParent
= args
.getHandle( pos
)->getVal
< const Lang::Class
>( (*i
)->funExpr_
->loc( ) );
329 parents
->push_back( std::pair
< RefCountPtr
< const Lang::Class
>, const Ast::ArgListExprs
* >( typedParent
, (*i
)->argList_
) );
332 std::map
< RefCountPtr
< const Lang::Class
>, std::list
< Ast::MemberDeclaration
* > > * overridesMap
= new std::map
< RefCountPtr
< const Lang::Class
>, std::list
< Ast::MemberDeclaration
* > >;
334 typedef std::map
< RefCountPtr
< const Lang::Class
>, std::map
< const char *, Ast::MemberDeclaration
*, charPtrLess
> > MapType
;
337 typedef typeof overrides_ ListType
;
338 for( ListType::const_iterator i
= overrides_
.begin( ); i
!= overrides_
.end( ); ++i
)
340 RefCountPtr
< const Lang::Class
> typedParent
= args
.getHandle( pos
)->getVal
< const Lang::Class
>( (*i
)->super_
->loc( ) );
342 std::map
< RefCountPtr
< const Lang::Class
>, std::list
< Ast::MemberDeclaration
* > >::iterator j
= overridesMap
->find( typedParent
);
343 if( j
== overridesMap
->end( ) )
345 j
= overridesMap
->insert( j
, std::pair
< RefCountPtr
< const Lang::Class
>, std::list
< Ast::MemberDeclaration
* > >( typedParent
, std::list
< Ast::MemberDeclaration
* >( ) ) );
347 std::map
< const char *, Ast::MemberDeclaration
*, charPtrLess
> & currentClassSeen
= seen
[ typedParent
];
348 for( std::list
< Ast::MemberDeclaration
* >::const_iterator k
= (*i
)->members_
->begin( ); k
!= (*i
)->members_
->end( ); ++k
)
350 std::map
< const char *, Ast::MemberDeclaration
*, charPtrLess
>::const_iterator l
= currentClassSeen
.find( (*k
)->id_
);
351 if( l
!= currentClassSeen
.end( ) )
353 throw Exceptions::MemberAlreadyDeclared( (*k
)->loc_
, (*k
)->id_
, l
->second
->loc_
);
355 currentClassSeen
[ (*k
)->id_
] = *k
;
357 j
->second
.push_back( *k
);
362 Lang::UserClass
* res
= new Lang::UserClass( this,
367 RefCountPtr
< std::map
< RefCountPtr
< const Lang::Class
>, std::list
< Ast::MemberDeclaration
* > > >( overridesMap
),
369 RefCountPtr
< const Lang::Class
> resRef
= RefCountPtr
< const Lang::Class
>( res
);
370 res
->setSelfRef( resRef
);
371 res
->setupAndCheck( isAbstract_
);
373 Kernel::ContRef cont
= evalState
->cont_
;
374 cont
->takeValue( resRef
,
379 Ast::ClassFunction::isInPublicGetSet( const char * field
) const
381 return publicGetSet_
.find( field
) != publicGetSet_
.end( );
385 Ast::ClassFunction::isInPublicSetSet( const char * field
) const
387 return publicSetSet_
.find( field
) != publicSetSet_
.end( );
391 Ast::ClassFunction::isInProtectedGetSet( const char * field
) const
393 return protectedGetSet_
.find( field
) != protectedGetSet_
.end( );
397 Ast::ClassFunction::isInProtectedSetSet( const char * field
) const
399 return protectedSetSet_
.find( field
) != protectedSetSet_
.end( );
403 Ast::ClassFunction::isInAbstractSet( const char * field
) const
405 return abstractSet_
.find( field
) != abstractSet_
.end( );
409 Ast::ClassFunction::isInFinalSet( const char * field
) const
411 return finalSet_
.find( field
) != finalSet_
.end( );
415 Ast::ClassFunction::isInTransformingSet( const char * field
) const
417 return transformingSet_
.find( field
) != transformingSet_
.end( );
420 Lang::Class::MessageMapType
421 Ast::ClassFunction::getLocalMessageMap( RefCountPtr
< const Lang::Class
> _myClass
) const
423 Lang::Class::MessageMapType res
;
425 typedef typeof abstractSet_ ListType
;
426 for( ListType::const_iterator i
= abstractSet_
.begin( ); i
!= abstractSet_
.end( ); ++i
)
428 res
[ Kernel::MethodId( _myClass
, *i
) ];
432 typedef typeof members_ ListType
;
433 for( ListType::const_iterator i
= members_
.begin( ); i
!= members_
.end( ); ++i
)
435 if( ( (*i
)->mode_
& Ast::MEMBER_METHOD
) == 0 )
439 std::set
< RefCountPtr
< const Lang::Class
> > & theSet
= res
[ Kernel::MethodId( _myClass
, (*i
)->id_
) ];
440 theSet
.insert( theSet
.begin( ), _myClass
);
447 Ast::ClassFunction::isRepeatableBase( ) const
449 return constructorFormals_
->argumentOrder_
->empty( );
454 Ast::ClassFunction::bindInitializationArguments( RefCountPtr
< const Lang::Class
> theClass
, Kernel::PassedEnv initEnv
, Kernel::Arguments
& args
) const
456 if( args
.size( ) != constructorFormals_
->size( ) )
458 throw Exceptions::UserArityMismatch( this, constructorFormals_
->size( ), args
.size( ), Exceptions::UserArityMismatch::VARIABLE
);
461 std::list
< Kernel::ValueRef
>::const_iterator val
= args
.begin( );
462 std::list
< Kernel::ValueRef
>::const_iterator end
= args
.end( );
463 std::list
< RefCountPtr
< const char > >::const_iterator formal
= constructorFormals_
->begin( );
464 Ast::SourceLocation dummy
;
465 for( ; val
!= end
; ++val
, ++formal
)
467 initEnv
->define( dummy
, *formal
, *val
, true ); /* true means constant; the initialization parameters shall not be confused with object states */
473 Ast::ClassFunction::setupInstance( Kernel::PassedEnv instanceEnv
, Kernel::PassedEnv privateEnv
, Kernel::EvalState
* evalState
, Kernel::PassedEnv initEnv
) const
475 throw Exceptions::NotImplemented( "ClassFunction::setupInstance" );
477 // typedef typeof members_ ListType;
478 // for( ListType::const_iterator i = members_.begin( ); i != members_.end( ); ++i )
480 // const Ast::MemberDeclaration & decl = **i;
482 // Kernel::PassedEnv * defineEnv = & instanceEnv;
483 // if( ( decl.mode & Ast::MEMBER_ACCESS_BITS ) == Ast::MEMBER_ACCESS_PRIVATE )
485 // defineEnv = & privateEnv;
488 // Kernel::PassedEnv & evalEnv = initEnv;
489 // if( ( decl.mode & Ast::MEMBER_METHOD ) != 0 )
491 // evalEnv = privateEnv;
494 // (*defineEnv)->define( decl.loc, decl.id, decl.init->value( dstgroup, pdfo, metaState, evalEnv ), ( decl.mode & ( Ast::MEMBER_METHOD | Ast::MEMBER_CONST ) ) != 0 );
499 Ast::ClassFunction::prepareInstance( Kernel::EvalState
* evalState
, Kernel::PassedEnv privateEnv
) const
501 throw Exceptions::NotImplemented( "ClassFunction::prepareInstance" );
503 // Ast::CodeBracket::evalSequence( preparations.begin( ), preparations.end( ), metaState, privateEnv, false );
506 const Ast::SourceLocation
&
507 Ast::ClassFunction::loc( ) const
513 Ast::PublicMethodReferenceFunction::PublicMethodReferenceFunction( const Ast::SourceLocation
& loc
, Ast::Expression
* obj
, MethodIdExpr
* methodId
)
514 : Lang::Function( 0 ), loc_( loc
, bool( ) ), obj_( obj
), methodClass_( methodId
->classPart_
), methodName_( strdup( methodId
->name_
) )
516 WARN_OR_THROW( Exceptions::InternalError( "Ast::PublicMethodReferenceFunction::PublicMethodReferenceFunction initializes Lang::Function with 0 pointer to formals.", true ) );
520 Ast::PublicMethodReferenceFunction::~PublicMethodReferenceFunction( )
527 Ast::PublicMethodReferenceFunction::push_exprs( Ast::ArgListExprs
* args
) const
529 args
->orderedExprs_
->push_back( obj_
);
530 args
->orderedExprs_
->push_back( methodClass_
);
534 Ast::PublicMethodReferenceFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
536 RefCountPtr
< const Lang::Value
> untypedObj
= args
.getValue( 0 );
537 Kernel::MethodId
methodId( args
.getHandle( 1 )->getVal
< const Lang::Class
>( methodClass_
->loc( ) ), methodName_
);
539 typedef const Lang::Instance ObjType
;
540 ObjType
* typedObj
= dynamic_cast< ObjType
* >( untypedObj
.getPtr( ) );
543 Kernel::ContRef cont
= evalState
->cont_
;
544 cont
->takeValue( typedObj
->getMethod( methodId
),
550 typedef const Lang::TransformedInstance ObjType
;
551 ObjType
* typedObj
= dynamic_cast< ObjType
* >( untypedObj
.getPtr( ) );
554 Kernel::ContRef cont
= evalState
->cont_
;
555 cont
->takeValue( typedObj
->getMethod( methodId
),
560 throw Exceptions::TypeMismatch( obj_
->loc( ), untypedObj
->getTypeName( ), Helpers::typeSetString( Lang::Instance::staticTypeName( ), Lang::TransformedInstance::staticTypeName( ) ) );
565 Ast::ProtectedMethodReferenceFunction::ProtectedMethodReferenceFunction( const Ast::SourceLocation
& loc
, const Ast::SourceLocation
& selfLoc
, Ast::Expression
* parent
, Ast::MethodIdExpr
* methodId
)
566 : Lang::Function( 0 ), loc_( loc
, bool( ) ), selfLoc_( selfLoc
, bool( ) ), parent_( parent
), methodClass_( methodId
->classPart_
), methodName_( strdup( methodId
->name_
) ), idKey_( new Kernel::Environment::LexicalKey
* ( 0 ) )
568 WARN_OR_THROW( Exceptions::InternalError( "Ast::PublicMethodReferenceFunction::PublicMethodReferenceFunction initializes Lang::Function with 0 pointer to formals.", true ) );
569 /* Currently, a runtime check is used to ensure that this expression indeed refers to a super instance.
574 Ast::ProtectedMethodReferenceFunction::~ProtectedMethodReferenceFunction( )
583 delete idKey_
; // This can be done only as long as this is not shared!
587 Ast::ProtectedMethodReferenceFunction::push_exprs( Ast::ArgListExprs
* args
) const
589 args
->orderedExprs_
->push_back( methodClass_
);
592 args
->orderedExprs_
->push_back( parent_
);
597 Ast::ProtectedMethodReferenceFunction::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
599 /* argument expressions shall be analyzed from the calling expression.
600 * Here, they are only used to locate errors.
607 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalVariableKey( selfLoc_
, Lang::SELF_ID
) );
609 catch( const Exceptions::LookupUnknown
& ball
)
611 throw Exceptions::MisplacedSuperReference( selfLoc_
);
617 Ast::ProtectedMethodReferenceFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
619 typedef const Lang::Instance SelfType
;
620 RefCountPtr
< const Lang::Value
> untypedSelf
= evalState
->env_
->getVarHandle( **idKey_
)->getUntyped( );
621 SelfType
* typedSelf
= dynamic_cast< SelfType
* >( untypedSelf
.getPtr( ) );
624 throw Exceptions::InternalError( strrefdup( "ProtectedMethodAccess: the self variable was not an instance." ) );
627 Kernel::MethodId
methodId( args
.getHandle( 0 )->getVal
< const Lang::Class
>( methodClass_
->loc( ) ), methodName_
);
631 RefCountPtr
< const Lang::Class
> typedParent
= args
.getHandle( 1 )->getVal
< const Lang::Class
>( parent_
->loc( ) );
632 Kernel::ContRef cont
= evalState
->cont_
;
633 cont
->takeValue( typedSelf
->superReference( typedParent
)->getLocalMethod( methodId
),
638 /* parent == 0 means a reference to a local override */
639 Kernel::ContRef cont
= evalState
->cont_
;
640 cont
->takeValue( typedSelf
->getLocalMethod( methodId
),
645 Ast::ProtectedMemberReferenceFunction::ProtectedMemberReferenceFunction( const Ast::SourceLocation
& loc
, const Ast::SourceLocation
& selfLoc
, Ast::Expression
* parent
, const Ast::SourceLocation
& idLoc
, const char * id
)
646 : Lang::Function( 0 ), loc_( loc
, bool( ) ), selfLoc_( selfLoc
, bool( ) ), parent_( parent
), idLoc_( idLoc
, bool( ) ), id_( id
), idKey_( new Kernel::Environment::LexicalKey
* ( 0 ) )
648 WARN_OR_THROW( Exceptions::InternalError( "Ast::ProtectedMemberReferenceFunction::ProtectedMemberReferenceFunction initializes Lang::Function with 0 pointer to formals.", true ) );
649 /* Currently, a runtime check is used to ensure that this expression indeed refers to a super instance.
653 Ast::ProtectedMemberReferenceFunction::~ProtectedMemberReferenceFunction( )
661 delete idKey_
; // This can be done only as long as this is not shared!
665 Ast::ProtectedMemberReferenceFunction::push_exprs( Ast::ArgListExprs
* args
) const
667 args
->orderedExprs_
->push_back( parent_
);
671 Ast::ProtectedMemberReferenceFunction::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
673 /* argument expressions shall be analyzed from the calling expression.
674 * Here, they are only used to locate errors.
681 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalVariableKey( selfLoc_
, Lang::SELF_ID
) );
683 catch( const Exceptions::LookupUnknown
& ball
)
685 throw Exceptions::MisplacedSuperReference( selfLoc_
);
691 Ast::ProtectedMemberReferenceFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
693 typedef const Lang::Instance SelfType
;
694 RefCountPtr
< const Lang::Value
> untypedSelf
= evalState
->env_
->getVarHandle( **idKey_
)->getUntyped( );
695 SelfType
* typedSelf
= dynamic_cast< SelfType
* >( untypedSelf
.getPtr( ) );
698 throw Exceptions::InternalError( strrefdup( "ProtectedMethodAccess: the self variable was not an instance." ) );
701 RefCountPtr
< const Lang::Class
> typedParent
= args
.getHandle( 0 )->getVal
< const Lang::Class
>( parent_
->loc( ) );
702 Kernel::ContRef cont
= evalState
->cont_
;
703 cont
->takeHandle( typedSelf
->superReference( typedParent
)->getLocalField( id_
),
708 Ast::ProtectedMemberInsertionFunction::ProtectedMemberInsertionFunction( const Ast::SourceLocation
& loc
, const Ast::SourceLocation
& selfLoc
, Ast::Expression
* parent
, const Ast::SourceLocation
& idLoc
, const char * id
, Ast::Expression
* pieceExpr
)
709 : Lang::Function( 0 ), loc_( loc
, bool( ) ), selfLoc_( selfLoc
, bool( ) ), parent_( parent
), idLoc_( idLoc
, bool( ) ), id_( id
), pieceExpr_( pieceExpr
), idKey_( new Kernel::Environment::LexicalKey
* ( 0 ) )
711 WARN_OR_THROW( Exceptions::InternalError( "Ast::ProtectedMemberInsertionFunction::ProtectedMemberInsertionFunction initializes Lang::Function with 0 pointer to formals.", true ) );
712 /* Currently, a runtime check is used to ensure that this expression indeed refers to a super instance.
716 Ast::ProtectedMemberInsertionFunction::~ProtectedMemberInsertionFunction( )
728 delete idKey_
; // This can be done only as long as this is not shared!
732 Ast::ProtectedMemberInsertionFunction::push_exprs( Ast::ArgListExprs
* args
) const
734 args
->orderedExprs_
->push_back( pieceExpr_
);
737 args
->orderedExprs_
->push_back( parent_
);
742 Ast::ProtectedMemberInsertionFunction::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
744 /* argument expressions shall be analyzed from the calling expression.
745 * Here, they are only used to locate errors.
752 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalStateKey( selfLoc_
, Lang::SELF_ID
, parent_
) );
754 catch( const Exceptions::LookupUnknown
& ball
)
756 throw Exceptions::MisplacedSuperReference( selfLoc_
);
762 Ast::ProtectedMemberInsertionFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
764 typedef const Lang::Instance SelfType
;
765 RefCountPtr
< const Lang::Value
> untypedSelf
= evalState
->env_
->getVarHandle( **idKey_
)->getUntyped( );
766 SelfType
* typedSelf
= dynamic_cast< SelfType
* >( untypedSelf
.getPtr( ) );
769 throw Exceptions::InternalError( strrefdup( "ProtectedMethodAccess: The self variable was not an instance." ) );
772 RefCountPtr
< const Lang::Value
> piece
= args
.getValue( 0 );
774 throw Exceptions::NotImplemented( "Tacking on fields." );
776 // if( parent_ == 0 )
778 // typedSelf->getField( id_, untypedSelf )->tackOn( evalState, piece, pieceExpr_->loc( ) );
782 // RefCountPtr< const Lang::Class > typedParent = args.getHandle( 1 )->getVal< const Lang::Class >( parent_->loc( ) );
783 // typedSelf->superReference( typedParent )->getLocalField( id_ )->tackOn( evalState, piece, pieceExpr_->loc( ) );