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 Henrik Tidefelt
19 #include "Shapes_Helpers_decls.h"
22 #include "shapesexceptions.h"
23 #include "classexceptions.h"
27 #include "shapescore.h"
31 using namespace Shapes
;
34 Ast::MethodIdExpr::MethodIdExpr( const Ast::SourceLocation
& loc
, Ast::Expression
* classPart
, const char * name
)
35 : loc_( loc
), classPart_( classPart
), name_( name
)
38 Ast::MethodIdExpr::~MethodIdExpr( )
42 // Ast::MethodIdExpr::identifier( Kernel::Environment::VariableHandle dstgroup, SimplePDF::PDF_out * pdfo, Kernel::GraphicsState * metaState, Kernel::PassedEnv env ) const
44 // RefCountPtr< const Lang::Value > untypedClass = classPart->value( dstgroup, pdfo, metaState, env );
45 // typedef const Lang::Class ArgType;
46 // RefCountPtr< ArgType > typedClass = untypedClass.down_cast< ArgType >( );
47 // if( typedClass == NullPtr< ArgType >( ) )
49 // throw Exceptions::TypeMismatch( classPart, untypedClass->getTypeName( ), ArgType::staticTypeName( ) );
51 // return Kernel::MethodId( typedClass, id->identifier( dstgroup, pdfo, metaState, env ) );
56 Ast::MemberDeclaration::MemberDeclaration( const Ast::SourceLocation
& loc
, const char * id
, Ast::Expression
* init
, const Ast::MemberMode
& mode
)
57 : loc_( loc
), id_( id
), init_( init
), mode_( mode
)
59 checkModeConsistency( );
62 Ast::MemberDeclaration::~MemberDeclaration( )
68 Ast::MemberDeclaration::addModeBits( const Ast::MemberMode
& bits
)
71 checkModeConsistency( );
75 Ast::MemberDeclaration::checkModeConsistency( )
77 if( ( mode_
& Ast::MEMBER_CONST
) != 0 && ( mode_
& ( Ast::MEMBER_ACCESS_PUBLIC_INSERT
| Ast::MEMBER_ACCESS_PROTECTED_INSERT
) ) != 0 )
79 throw Exceptions::ParserError( loc_
, strrefdup( "The member cannot be declared both const and assignable." ) );
84 Ast::ClassSection::ClassSection( )
87 Ast::ClassSection::~ClassSection( )
91 Ast::MemberSection::MemberSection( )
94 Ast::MemberSection::~MemberSection( )
96 /* 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.
101 Ast::MemberSection::addModeBits( const Ast::MemberMode
& bits
)
103 for( iterator i
= begin( ); i
!= end( ); ++i
)
105 (*i
)->addModeBits( bits
);
110 Ast::PrepareSection::PrepareSection( const Ast::SourceLocation
& loc
, std::list
< Ast::Node
* > * nodes
)
111 : loc_( loc
), nodes_( nodes
)
114 Ast::PrepareSection::~PrepareSection( )
116 /* 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.
117 * However, the list shall be deleted.
123 Ast::AbstractSection::AbstractSection( const Ast::SourceLocation
& loc
, const std::list
< RefCountPtr
< const char > > * methods
)
124 : loc_( loc
), methods_( methods
)
127 Ast::AbstractSection::~AbstractSection( )
133 Ast::OverridesSection::OverridesSection( Ast::Expression
* super
, Ast::MemberSection
* members
)
134 : super_( super
), members_( members
)
137 Ast::OverridesSection::~OverridesSection( )
144 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
)
145 : Lang::Function( new Kernel::EvaluatedFormals( Ast::FileID::build_internal( "< class construction >" ), true ) ), loc_( loc
), name_( name
), constructorFormals_( constructorFormals
), parentsWithInitArgs_( parentsWithInitArgs
), isAbstract_( ( classMode
& Ast::CLASS_MODE_ABSTRACT
) != 0 ), isFinal_( ( classMode
& Ast::CLASS_MODE_FINAL
) != 0 )
147 for( std::list
< Ast::ClassSection
* >::iterator i
= sections
->begin( ); i
!= sections
->end( ); ++i
)
150 typedef Ast::MemberSection T
;
151 T
* memberSection
= dynamic_cast< T
* >( *i
);
152 if( memberSection
!= 0 )
154 for( std::list
< Ast::MemberDeclaration
* >::iterator j
= memberSection
->begin( );
155 j
!= memberSection
->end( );
158 members_
.push_back( *j
);
165 typedef Ast::PrepareSection T
;
166 T
* prepareSection
= dynamic_cast< T
* >( *i
);
167 if( prepareSection
!= 0 )
169 for( std::list
< Ast::Node
* >::iterator j
= prepareSection
->nodes_
->begin( );
170 j
!= prepareSection
->nodes_
->end( );
173 preparations_
.push_back( *j
);
180 typedef Ast::OverridesSection T
;
181 T
* overridesSection
= dynamic_cast< T
* >( *i
);
182 if( overridesSection
!= 0 )
184 overrides_
.push_back( overridesSection
);
189 typedef Ast::AbstractSection T
;
190 T
* abstractSection
= dynamic_cast< T
* >( *i
);
191 if( abstractSection
!= 0 )
193 for( std::list
< RefCountPtr
< const char > >::const_iterator j
= abstractSection
->methods_
->begin( );
194 j
!= abstractSection
->methods_
->end( );
197 abstractSet_
.insert( strdup( j
->getPtr( ) ) );
202 throw Exceptions::InternalError( strrefdup( "ClassFunction::ClassFunction: the ClassSection was neither of the expected types" ) );
207 typedef std::map
< const char *, Ast::MemberDeclaration
*, charPtrLess
> MapType
;
209 for( std::list
< Ast::MemberDeclaration
* >::const_iterator i
= members_
.begin( ); i
!= members_
.end( ); ++i
)
212 if( abstractSet_
.find( (*i
)->id_
) != abstractSet_
.end( ) )
214 throw Exceptions::MemberAlsoAbstract( (*i
)->loc_
, (*i
)->id_
, Ast::THE_UNKNOWN_LOCATION
);
216 MapType::const_iterator j
= seen
.find( (*i
)->id_
);
217 if( j
!= seen
.end( ) )
219 throw Exceptions::MemberAlreadyDeclared( (*i
)->loc_
, (*i
)->id_
, j
->second
->loc_
);
221 seen
[ (*i
)->id_
] = *i
;
223 if( ( (*i
)->mode_
& Ast::MEMBER_ACCESS_PUBLIC_GET
) != 0 )
225 if( ( (*i
)->mode_
& Ast::MEMBER_METHOD
) == 0 && ! isFinal_
)
227 throw Exceptions::PublicGetSetInNonfinalClass( (*i
)->loc_
, (*i
)->id_
);
229 publicGetSet_
.insert( (*i
)->id_
);
231 if( ( (*i
)->mode_
& Ast::MEMBER_ACCESS_PROTECTED_GET
) != 0 )
233 protectedGetSet_
.insert( (*i
)->id_
);
235 if( ( (*i
)->mode_
& Ast::MEMBER_ACCESS_PUBLIC_INSERT
) != 0 )
237 if( ( (*i
)->mode_
& Ast::MEMBER_METHOD
) == 0 && ! isFinal_
)
239 throw Exceptions::PublicGetSetInNonfinalClass( (*i
)->loc_
, (*i
)->id_
);
241 publicSetSet_
.insert( (*i
)->id_
);
243 if( ( (*i
)->mode_
& Ast::MEMBER_ACCESS_PROTECTED_INSERT
) != 0 )
245 protectedSetSet_
.insert( (*i
)->id_
);
247 if( ( (*i
)->mode_
& Ast::MEMBER_FINAL
) != 0 )
249 finalSet_
.insert( (*i
)->id_
);
251 if( ( (*i
)->mode_
& Ast::MEMBER_TRANSFORMING
) != 0 )
253 if( ( (*i
)->mode_
& Ast::MEMBER_METHOD
) == 0 && ! isFinal_
)
255 throw Exceptions::TransformingMemberInNonfinalClass( (*i
)->loc_
, (*i
)->id_
);
257 transformingSet_
.insert( (*i
)->id_
);
263 Ast::ClassFunction::~ClassFunction( )
267 delete constructorFormals_
;
269 for( std::list
< const Ast::CallExpr
* >::iterator i
= parentsWithInitArgs_
->begin( );
270 i
!= parentsWithInitArgs_
->end( );
275 delete parentsWithInitArgs_
;
277 /* preparations_ and members_ delete their elements by themselves
283 Ast::ClassFunction::push_exprs( Ast::ArgListExprs
* args
) const
285 args
->orderedExprs_
->push_back( name_
);
287 constructorFormals_
->push_exprs( args
);
289 typedef std::list
< std::pair
< RefCountPtr
< const Lang::Class
>, const Ast::ArgListExprs
* > > ParentClassList
;
290 RefCountPtr
< ParentClassList
> parents
= RefCountPtr
< ParentClassList
>( new ParentClassList
);
291 for( std::list
< const Ast::CallExpr
* >::iterator i
= parentsWithInitArgs_
->begin( );
292 i
!= parentsWithInitArgs_
->end( );
295 args
->orderedExprs_
->push_back( (*i
)->funExpr_
);
299 typedef std::map
< RefCountPtr
< const Lang::Class
>, std::map
< const char *, Ast::MemberDeclaration
*, charPtrLess
> > MapType
;
302 typedef typeof overrides_ ListType
;
303 for( ListType::const_iterator i
= overrides_
.begin( ); i
!= overrides_
.end( ); ++i
)
305 args
->orderedExprs_
->push_back( (*i
)->super_
);
312 Ast::ClassFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
315 RefCountPtr
< const Lang::String
> typedName
= args
.getHandle( pos
)->getVal
< const Lang::String
>( name_
->loc( ) );
318 Kernel::EvaluatedFormals
* evaluatedFormals
= constructorFormals_
->newEvaluatedFormals( args
, & pos
);
320 typedef std::list
< std::pair
< RefCountPtr
< const Lang::Class
>, const Ast::ArgListExprs
* > > ParentClassList
;
321 RefCountPtr
< ParentClassList
> parents
= RefCountPtr
< ParentClassList
>( new ParentClassList
);
322 for( std::list
< const Ast::CallExpr
* >::iterator i
= parentsWithInitArgs_
->begin( );
323 i
!= parentsWithInitArgs_
->end( );
326 RefCountPtr
< const Lang::Class
> typedParent
= args
.getHandle( pos
)->getVal
< const Lang::Class
>( (*i
)->funExpr_
->loc( ) );
328 parents
->push_back( std::pair
< RefCountPtr
< const Lang::Class
>, const Ast::ArgListExprs
* >( typedParent
, (*i
)->argList_
) );
331 std::map
< RefCountPtr
< const Lang::Class
>, std::list
< Ast::MemberDeclaration
* > > * overridesMap
= new std::map
< RefCountPtr
< const Lang::Class
>, std::list
< Ast::MemberDeclaration
* > >;
333 typedef std::map
< RefCountPtr
< const Lang::Class
>, std::map
< const char *, Ast::MemberDeclaration
*, charPtrLess
> > MapType
;
336 typedef typeof overrides_ ListType
;
337 for( ListType::const_iterator i
= overrides_
.begin( ); i
!= overrides_
.end( ); ++i
)
339 RefCountPtr
< const Lang::Class
> typedParent
= args
.getHandle( pos
)->getVal
< const Lang::Class
>( (*i
)->super_
->loc( ) );
341 std::map
< RefCountPtr
< const Lang::Class
>, std::list
< Ast::MemberDeclaration
* > >::iterator j
= overridesMap
->find( typedParent
);
342 if( j
== overridesMap
->end( ) )
344 j
= overridesMap
->insert( j
, std::pair
< RefCountPtr
< const Lang::Class
>, std::list
< Ast::MemberDeclaration
* > >( typedParent
, std::list
< Ast::MemberDeclaration
* >( ) ) );
346 std::map
< const char *, Ast::MemberDeclaration
*, charPtrLess
> & currentClassSeen
= seen
[ typedParent
];
347 for( std::list
< Ast::MemberDeclaration
* >::const_iterator k
= (*i
)->members_
->begin( ); k
!= (*i
)->members_
->end( ); ++k
)
349 std::map
< const char *, Ast::MemberDeclaration
*, charPtrLess
>::const_iterator l
= currentClassSeen
.find( (*k
)->id_
);
350 if( l
!= currentClassSeen
.end( ) )
352 throw Exceptions::MemberAlreadyDeclared( (*k
)->loc_
, (*k
)->id_
, l
->second
->loc_
);
354 currentClassSeen
[ (*k
)->id_
] = *k
;
356 j
->second
.push_back( *k
);
361 Lang::UserClass
* res
= new Lang::UserClass( this,
366 RefCountPtr
< std::map
< RefCountPtr
< const Lang::Class
>, std::list
< Ast::MemberDeclaration
* > > >( overridesMap
),
368 RefCountPtr
< const Lang::Class
> resRef
= RefCountPtr
< const Lang::Class
>( res
);
369 res
->setSelfRef( resRef
);
370 res
->setupAndCheck( isAbstract_
);
372 Kernel::ContRef cont
= evalState
->cont_
;
373 cont
->takeValue( resRef
,
378 Ast::ClassFunction::isInPublicGetSet( const char * field
) const
380 return publicGetSet_
.find( field
) != publicGetSet_
.end( );
384 Ast::ClassFunction::isInPublicSetSet( const char * field
) const
386 return publicSetSet_
.find( field
) != publicSetSet_
.end( );
390 Ast::ClassFunction::isInProtectedGetSet( const char * field
) const
392 return protectedGetSet_
.find( field
) != protectedGetSet_
.end( );
396 Ast::ClassFunction::isInProtectedSetSet( const char * field
) const
398 return protectedSetSet_
.find( field
) != protectedSetSet_
.end( );
402 Ast::ClassFunction::isInAbstractSet( const char * field
) const
404 return abstractSet_
.find( field
) != abstractSet_
.end( );
408 Ast::ClassFunction::isInFinalSet( const char * field
) const
410 return finalSet_
.find( field
) != finalSet_
.end( );
414 Ast::ClassFunction::isInTransformingSet( const char * field
) const
416 return transformingSet_
.find( field
) != transformingSet_
.end( );
419 Lang::Class::MessageMapType
420 Ast::ClassFunction::getLocalMessageMap( RefCountPtr
< const Lang::Class
> _myClass
) const
422 Lang::Class::MessageMapType res
;
424 typedef typeof abstractSet_ ListType
;
425 for( ListType::const_iterator i
= abstractSet_
.begin( ); i
!= abstractSet_
.end( ); ++i
)
427 res
[ Kernel::MethodId( _myClass
, *i
) ];
431 typedef typeof members_ ListType
;
432 for( ListType::const_iterator i
= members_
.begin( ); i
!= members_
.end( ); ++i
)
434 if( ( (*i
)->mode_
& Ast::MEMBER_METHOD
) == 0 )
438 std::set
< RefCountPtr
< const Lang::Class
> > & theSet
= res
[ Kernel::MethodId( _myClass
, (*i
)->id_
) ];
439 theSet
.insert( theSet
.begin( ), _myClass
);
446 Ast::ClassFunction::isRepeatableBase( ) const
448 return constructorFormals_
->argumentOrder_
->empty( );
453 Ast::ClassFunction::bindInitializationArguments( RefCountPtr
< const Lang::Class
> theClass
, Kernel::PassedEnv initEnv
, Kernel::Arguments
& args
) const
455 if( args
.size( ) != constructorFormals_
->size( ) )
457 throw Exceptions::UserArityMismatch( this, constructorFormals_
->size( ), args
.size( ), Exceptions::UserArityMismatch::VARIABLE
);
460 std::list
< Kernel::ValueRef
>::const_iterator val
= args
.begin( );
461 std::list
< Kernel::ValueRef
>::const_iterator end
= args
.end( );
462 std::list
< RefCountPtr
< const char > >::const_iterator formal
= constructorFormals_
->begin( );
463 Ast::SourceLocation dummy
;
464 for( ; val
!= end
; ++val
, ++formal
)
466 initEnv
->define( dummy
, *formal
, *val
, true ); /* true means constant; the initialization parameters shall not be confused with object states */
472 Ast::ClassFunction::setupInstance( Kernel::PassedEnv instanceEnv
, Kernel::PassedEnv privateEnv
, Kernel::EvalState
* evalState
, Kernel::PassedEnv initEnv
) const
474 throw Exceptions::NotImplemented( "ClassFunction::setupInstance" );
476 // typedef typeof members_ ListType;
477 // for( ListType::const_iterator i = members_.begin( ); i != members_.end( ); ++i )
479 // const Ast::MemberDeclaration & decl = **i;
481 // Kernel::PassedEnv * defineEnv = & instanceEnv;
482 // if( ( decl.mode & Ast::MEMBER_ACCESS_BITS ) == Ast::MEMBER_ACCESS_PRIVATE )
484 // defineEnv = & privateEnv;
487 // Kernel::PassedEnv & evalEnv = initEnv;
488 // if( ( decl.mode & Ast::MEMBER_METHOD ) != 0 )
490 // evalEnv = privateEnv;
493 // (*defineEnv)->define( decl.loc, decl.id, decl.init->value( dstgroup, pdfo, metaState, evalEnv ), ( decl.mode & ( Ast::MEMBER_METHOD | Ast::MEMBER_CONST ) ) != 0 );
498 Ast::ClassFunction::prepareInstance( Kernel::EvalState
* evalState
, Kernel::PassedEnv privateEnv
) const
500 throw Exceptions::NotImplemented( "ClassFunction::prepareInstance" );
502 // Ast::CodeBracket::evalSequence( preparations.begin( ), preparations.end( ), metaState, privateEnv, false );
505 const Ast::SourceLocation
&
506 Ast::ClassFunction::loc( ) const
512 Ast::PublicMethodReferenceFunction::PublicMethodReferenceFunction( const Ast::SourceLocation
& loc
, Ast::Expression
* obj
, MethodIdExpr
* methodId
)
513 : Lang::Function( 0 ), loc_( loc
), obj_( obj
), methodClass_( methodId
->classPart_
), methodName_( strdup( methodId
->name_
) )
515 std::cerr
<< "Warning: Ast::PublicMethodReferenceFunction::PublicMethodReferenceFunction initializes Lang::Function with 0 pointer to formals." << std::endl
;
519 Ast::PublicMethodReferenceFunction::~PublicMethodReferenceFunction( )
526 Ast::PublicMethodReferenceFunction::push_exprs( Ast::ArgListExprs
* args
) const
528 args
->orderedExprs_
->push_back( obj_
);
529 args
->orderedExprs_
->push_back( methodClass_
);
533 Ast::PublicMethodReferenceFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
535 RefCountPtr
< const Lang::Value
> untypedObj
= args
.getValue( 0 );
536 Kernel::MethodId
methodId( args
.getHandle( 1 )->getVal
< const Lang::Class
>( methodClass_
->loc( ) ), methodName_
);
538 typedef const Lang::Instance ObjType
;
539 ObjType
* typedObj
= dynamic_cast< ObjType
* >( untypedObj
.getPtr( ) );
542 Kernel::ContRef cont
= evalState
->cont_
;
543 cont
->takeValue( typedObj
->getMethod( methodId
),
549 typedef const Lang::TransformedInstance ObjType
;
550 ObjType
* typedObj
= dynamic_cast< ObjType
* >( untypedObj
.getPtr( ) );
553 Kernel::ContRef cont
= evalState
->cont_
;
554 cont
->takeValue( typedObj
->getMethod( methodId
),
559 throw Exceptions::TypeMismatch( obj_
->loc( ), untypedObj
->getTypeName( ), Helpers::typeSetString( Lang::Instance::staticTypeName( ), Lang::TransformedInstance::staticTypeName( ) ) );
564 Ast::ProtectedMethodReferenceFunction::ProtectedMethodReferenceFunction( const Ast::SourceLocation
& loc
, const Ast::SourceLocation
& selfLoc
, Ast::Expression
* parent
, Ast::MethodIdExpr
* methodId
)
565 : Lang::Function( 0 ), loc_( loc
), selfLoc_( selfLoc
), parent_( parent
), methodClass_( methodId
->classPart_
), methodName_( strdup( methodId
->name_
) ), idKey_( new Kernel::Environment::LexicalKey
* ( 0 ) )
567 std::cerr
<< "Warning: Ast::PublicMethodReferenceFunction::PublicMethodReferenceFunction initializes Lang::Function with 0 pointer to formals." << std::endl
;
568 /* Currently, a runtime check is used to ensure that this expression indeed refers to a super instance.
573 Ast::ProtectedMethodReferenceFunction::~ProtectedMethodReferenceFunction( )
582 delete idKey_
; // This can be done only as long as this is not shared!
586 Ast::ProtectedMethodReferenceFunction::push_exprs( Ast::ArgListExprs
* args
) const
588 args
->orderedExprs_
->push_back( methodClass_
);
591 args
->orderedExprs_
->push_back( parent_
);
596 Ast::ProtectedMethodReferenceFunction::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
598 /* argument expressions shall be analyzed from the calling expression.
599 * Here, they are only used to locate errors.
606 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalVariableKey( selfLoc_
, Lang::SELF_ID
) );
608 catch( const Exceptions::LookupUnknown
& ball
)
610 throw Exceptions::MisplacedSuperReference( selfLoc_
);
616 Ast::ProtectedMethodReferenceFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
618 typedef const Lang::Instance SelfType
;
619 RefCountPtr
< const Lang::Value
> untypedSelf
= evalState
->env_
->getVarHandle( **idKey_
)->getUntyped( );
620 SelfType
* typedSelf
= dynamic_cast< SelfType
* >( untypedSelf
.getPtr( ) );
623 throw Exceptions::InternalError( strrefdup( "ProtectedMethodAccess: the self variable was not an instance." ) );
626 Kernel::MethodId
methodId( args
.getHandle( 0 )->getVal
< const Lang::Class
>( methodClass_
->loc( ) ), methodName_
);
630 RefCountPtr
< const Lang::Class
> typedParent
= args
.getHandle( 1 )->getVal
< const Lang::Class
>( parent_
->loc( ) );
631 Kernel::ContRef cont
= evalState
->cont_
;
632 cont
->takeValue( typedSelf
->superReference( typedParent
)->getLocalMethod( methodId
),
637 /* parent == 0 means a reference to a local override */
638 Kernel::ContRef cont
= evalState
->cont_
;
639 cont
->takeValue( typedSelf
->getLocalMethod( methodId
),
644 Ast::ProtectedMemberReferenceFunction::ProtectedMemberReferenceFunction( const Ast::SourceLocation
& loc
, const Ast::SourceLocation
& selfLoc
, Ast::Expression
* parent
, const Ast::SourceLocation
& idLoc
, const char * id
)
645 : Lang::Function( 0 ), loc_( loc
), selfLoc_( selfLoc
), parent_( parent
), idLoc_( idLoc
), id_( id
), idKey_( new Kernel::Environment::LexicalKey
* ( 0 ) )
647 std::cerr
<< "Warning: Ast::ProtectedMemberReferenceFunction::ProtectedMemberReferenceFunction initializes Lang::Function with 0 pointer to formals." << std::endl
;
648 /* Currently, a runtime check is used to ensure that this expression indeed refers to a super instance.
652 Ast::ProtectedMemberReferenceFunction::~ProtectedMemberReferenceFunction( )
660 delete idKey_
; // This can be done only as long as this is not shared!
664 Ast::ProtectedMemberReferenceFunction::push_exprs( Ast::ArgListExprs
* args
) const
666 args
->orderedExprs_
->push_back( parent_
);
670 Ast::ProtectedMemberReferenceFunction::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
672 /* argument expressions shall be analyzed from the calling expression.
673 * Here, they are only used to locate errors.
680 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalVariableKey( selfLoc_
, Lang::SELF_ID
) );
682 catch( const Exceptions::LookupUnknown
& ball
)
684 throw Exceptions::MisplacedSuperReference( selfLoc_
);
690 Ast::ProtectedMemberReferenceFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
692 typedef const Lang::Instance SelfType
;
693 RefCountPtr
< const Lang::Value
> untypedSelf
= evalState
->env_
->getVarHandle( **idKey_
)->getUntyped( );
694 SelfType
* typedSelf
= dynamic_cast< SelfType
* >( untypedSelf
.getPtr( ) );
697 throw Exceptions::InternalError( strrefdup( "ProtectedMethodAccess: the self variable was not an instance." ) );
700 RefCountPtr
< const Lang::Class
> typedParent
= args
.getHandle( 0 )->getVal
< const Lang::Class
>( parent_
->loc( ) );
701 Kernel::ContRef cont
= evalState
->cont_
;
702 cont
->takeHandle( typedSelf
->superReference( typedParent
)->getLocalField( id_
),
707 Ast::ProtectedMemberInsertionFunction::ProtectedMemberInsertionFunction( const Ast::SourceLocation
& loc
, const Ast::SourceLocation
& selfLoc
, Ast::Expression
* parent
, const Ast::SourceLocation
& idLoc
, const char * id
, Ast::Expression
* pieceExpr
)
708 : Lang::Function( 0 ), loc_( loc
), selfLoc_( selfLoc
), parent_( parent
), idLoc_( idLoc
), id_( id
), pieceExpr_( pieceExpr
), idKey_( new Kernel::Environment::LexicalKey
* ( 0 ) )
710 std::cerr
<< "Warning: Ast::ProtectedMemberInsertionFunction::ProtectedMemberInsertionFunction initializes Lang::Function with 0 pointer to formals." << std::endl
;
711 /* Currently, a runtime check is used to ensure that this expression indeed refers to a super instance.
715 Ast::ProtectedMemberInsertionFunction::~ProtectedMemberInsertionFunction( )
727 delete idKey_
; // This can be done only as long as this is not shared!
731 Ast::ProtectedMemberInsertionFunction::push_exprs( Ast::ArgListExprs
* args
) const
733 args
->orderedExprs_
->push_back( pieceExpr_
);
736 args
->orderedExprs_
->push_back( parent_
);
741 Ast::ProtectedMemberInsertionFunction::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
743 /* argument expressions shall be analyzed from the calling expression.
744 * Here, they are only used to locate errors.
751 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalStateKey( selfLoc_
, Lang::SELF_ID
) );
753 catch( const Exceptions::LookupUnknown
& ball
)
755 throw Exceptions::MisplacedSuperReference( selfLoc_
);
761 Ast::ProtectedMemberInsertionFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
763 typedef const Lang::Instance SelfType
;
764 RefCountPtr
< const Lang::Value
> untypedSelf
= evalState
->env_
->getVarHandle( **idKey_
)->getUntyped( );
765 SelfType
* typedSelf
= dynamic_cast< SelfType
* >( untypedSelf
.getPtr( ) );
768 throw Exceptions::InternalError( strrefdup( "ProtectedMethodAccess: the self variable was not an instance." ) );
771 RefCountPtr
< const Lang::Value
> piece
= args
.getValue( 0 );
773 throw Exceptions::NotImplemented( "Tacking on fields." );
775 // if( parent_ == 0 )
777 // typedSelf->getField( id_, untypedSelf )->tackOn( evalState, piece, pieceExpr_->loc( ) );
781 // RefCountPtr< const Lang::Class > typedParent = args.getHandle( 1 )->getVal< const Lang::Class >( parent_->loc( ) );
782 // typedSelf->superReference( typedParent )->getLocalField( id_ )->tackOn( evalState, piece, pieceExpr_->loc( ) );