Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <basic/sbx.hxx>
21 : #include "sbcomp.hxx"
22 : #include "sbunoobj.hxx"
23 : #include <svtools/miscopt.hxx>
24 : #include <com/sun/star/reflection/theCoreReflection.hpp>
25 : #include <comphelper/namedvaluecollection.hxx>
26 : #include <comphelper/processfactory.hxx>
27 : #include <comphelper/configurationhelper.hxx>
28 : #include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp>
29 : #include <com/sun/star/reflection/XIdlMethod.hpp>
30 : #include <com/sun/star/uno/Exception.hpp>
31 : #include <basic/codecompletecache.hxx>
32 :
33 : using namespace ::com::sun::star;
34 : using namespace ::com::sun::star::uno;
35 :
36 : SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj );
37 :
38 : // Declaration of a variable
39 : // If there are errors it will be parsed up to the comma or the newline.
40 : // Return-value: a new instance, which were inserted and then deleted.
41 : // Array-Indexex were returned as SbiDimList
42 :
43 0 : SbiSymDef* SbiParser::VarDecl( SbiDimList** ppDim, bool bStatic, bool bConst )
44 : {
45 0 : bool bWithEvents = false;
46 0 : if( Peek() == WITHEVENTS )
47 : {
48 0 : Next();
49 0 : bWithEvents = true;
50 : }
51 0 : if( !TestSymbol() ) return NULL;
52 0 : SbxDataType t = eScanType;
53 0 : SbiSymDef* pDef = bConst ? new SbiConstDef( aSym ) : new SbiSymDef( aSym );
54 0 : SbiDimList* pDim = NULL;
55 : // Brackets?
56 0 : if( Peek() == LPAREN )
57 : {
58 0 : pDim = new SbiDimList( this );
59 0 : if( !pDim->GetDims() )
60 0 : pDef->SetWithBrackets();
61 : }
62 0 : pDef->SetType( t );
63 0 : if( bStatic )
64 0 : pDef->SetStatic();
65 0 : if( bWithEvents )
66 0 : pDef->SetWithEvents();
67 0 : TypeDecl( *pDef );
68 0 : if( !ppDim && pDim )
69 : {
70 0 : if(pDim->GetDims() )
71 0 : Error( SbERR_EXPECTED, "()" );
72 0 : delete pDim;
73 : }
74 0 : else if( ppDim )
75 0 : *ppDim = pDim;
76 0 : return pDef;
77 : }
78 :
79 : // Resolving of a AS-Type-Declaration
80 : // The data type were inserted into the handed over variable
81 :
82 0 : void SbiParser::TypeDecl( SbiSymDef& rDef, bool bAsNewAlreadyParsed )
83 : {
84 0 : SbxDataType eType = rDef.GetType();
85 0 : if( bAsNewAlreadyParsed || Peek() == AS )
86 : {
87 0 : short nSize = 0;
88 0 : if( !bAsNewAlreadyParsed )
89 0 : Next();
90 0 : rDef.SetDefinedAs();
91 0 : SbiToken eTok = Next();
92 0 : if( !bAsNewAlreadyParsed && eTok == NEW )
93 : {
94 0 : rDef.SetNew();
95 0 : eTok = Next();
96 : }
97 0 : switch( eTok )
98 : {
99 : case ANY:
100 0 : if( rDef.IsNew() )
101 0 : Error( SbERR_SYNTAX );
102 0 : eType = SbxVARIANT; break;
103 : case TINTEGER:
104 : case TLONG:
105 : case TSINGLE:
106 : case TDOUBLE:
107 : case TCURRENCY:
108 : case TDATE:
109 : case TSTRING:
110 : case TOBJECT:
111 : case _ERROR_:
112 : case TBOOLEAN:
113 : case TVARIANT:
114 : case TBYTE:
115 0 : if( rDef.IsNew() )
116 0 : Error( SbERR_SYNTAX );
117 0 : eType = (eTok==TBYTE) ? SbxBYTE : SbxDataType( eTok - TINTEGER + SbxINTEGER );
118 0 : if( eType == SbxSTRING )
119 : {
120 : // STRING*n ?
121 0 : if( Peek() == MUL )
122 : { // fixed size!
123 0 : Next();
124 0 : SbiConstExpression aSize( this );
125 0 : nSize = aSize.GetShortValue();
126 0 : if( nSize < 0 || (bVBASupportOn && nSize <= 0) )
127 0 : Error( SbERR_OUT_OF_RANGE );
128 : else
129 0 : rDef.SetFixedStringLength( nSize );
130 : }
131 : }
132 0 : break;
133 : case SYMBOL: // can only be a TYPE or a object class!
134 0 : if( eScanType != SbxVARIANT )
135 0 : Error( SbERR_SYNTAX );
136 : else
137 : {
138 0 : OUString aCompleteName = aSym;
139 :
140 : // #52709 DIM AS NEW for Uno with full-qualified name
141 0 : if( Peek() == DOT )
142 : {
143 0 : OUString aDotStr( '.' );
144 0 : while( Peek() == DOT )
145 : {
146 0 : aCompleteName += aDotStr;
147 0 : Next();
148 0 : SbiToken ePeekTok = Peek();
149 0 : if( ePeekTok == SYMBOL || IsKwd( ePeekTok ) )
150 : {
151 0 : Next();
152 0 : aCompleteName += aSym;
153 : }
154 : else
155 : {
156 0 : Next();
157 0 : Error( SbERR_UNEXPECTED, SYMBOL );
158 0 : break;
159 : }
160 0 : }
161 : }
162 0 : else if( rEnumArray->Find( aCompleteName, SbxCLASS_OBJECT ) || ( IsVBASupportOn() && VBAConstantHelper::instance().isVBAConstantType( aCompleteName ) ) )
163 : {
164 0 : eType = SbxLONG;
165 0 : break;
166 : }
167 :
168 : // Take over in the string pool
169 0 : rDef.SetTypeId( aGblStrings.Add( aCompleteName ) );
170 :
171 0 : if( rDef.IsNew() && pProc == NULL )
172 0 : aRequiredTypes.push_back( aCompleteName );
173 : }
174 0 : eType = SbxOBJECT;
175 0 : break;
176 : case FIXSTRING: // new syntax for complex UNO types
177 0 : rDef.SetTypeId( aGblStrings.Add( aSym ) );
178 0 : eType = SbxOBJECT;
179 0 : break;
180 : default:
181 0 : Error( SbERR_UNEXPECTED, eTok );
182 0 : Next();
183 : }
184 : // The variable could have been declared with a suffix
185 0 : if( rDef.GetType() != SbxVARIANT )
186 : {
187 0 : if( rDef.GetType() != eType )
188 0 : Error( SbERR_VAR_DEFINED, rDef.GetName() );
189 0 : else if( eType == SbxSTRING && rDef.GetLen() != nSize )
190 0 : Error( SbERR_VAR_DEFINED, rDef.GetName() );
191 : }
192 0 : rDef.SetType( eType );
193 0 : rDef.SetLen( nSize );
194 : }
195 0 : }
196 :
197 : // Here variables, arrays and structures were definied.
198 : // DIM/PRIVATE/PUBLIC/GLOBAL
199 :
200 0 : void SbiParser::Dim()
201 : {
202 0 : DefVar( _DIM, ( pProc && bVBASupportOn ) ? pProc->IsStatic() : false );
203 0 : }
204 :
205 0 : void SbiParser::DefVar( SbiOpcode eOp, bool bStatic )
206 : {
207 0 : SbiSymPool* pOldPool = pPool;
208 0 : bool bSwitchPool = false;
209 0 : bool bPersistantGlobal = false;
210 0 : SbiToken eFirstTok = eCurTok;
211 :
212 0 : if( pProc && ( eCurTok == GLOBAL || eCurTok == PUBLIC || eCurTok == PRIVATE ) )
213 0 : Error( SbERR_NOT_IN_SUBR, eCurTok );
214 0 : if( eCurTok == PUBLIC || eCurTok == GLOBAL )
215 : {
216 0 : bSwitchPool = true; // at the right moment switch to the global pool
217 0 : if( eCurTok == GLOBAL )
218 0 : bPersistantGlobal = true;
219 : }
220 : // behavior in VBA is that a module scope variable's lifetime is
221 : // tied to the document. e.g. a module scope variable is global
222 0 : if( GetBasic()->IsDocBasic() && bVBASupportOn && !pProc )
223 0 : bPersistantGlobal = true;
224 : // PRIVATE is a synonymous for DIM
225 : // _CONST_?
226 0 : bool bConst = false;
227 0 : if( eCurTok == _CONST_ )
228 0 : bConst = true;
229 0 : else if( Peek() == _CONST_ )
230 0 : Next(), bConst = true;
231 :
232 : // #110004 It can also be a sub/function
233 0 : if( !bConst && (eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY ||
234 0 : eCurTok == STATIC || eCurTok == ENUM || eCurTok == DECLARE || eCurTok == TYPE) )
235 : {
236 : // Next token is read here, because !bConst
237 0 : bool bPrivate = ( eFirstTok == PRIVATE );
238 :
239 0 : if( eCurTok == STATIC )
240 : {
241 0 : Next();
242 0 : DefStatic( bPrivate );
243 : }
244 0 : else if( eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY )
245 : {
246 : // End global chain if necessary (not done in
247 : // SbiParser::Parse() under these conditions
248 0 : if( bNewGblDefs && nGblChain == 0 )
249 : {
250 0 : nGblChain = aGen.Gen( _JUMP, 0 );
251 0 : bNewGblDefs = false;
252 : }
253 0 : Next();
254 0 : DefProc( false, bPrivate );
255 0 : return;
256 : }
257 0 : else if( eCurTok == ENUM )
258 : {
259 0 : Next();
260 0 : DefEnum( bPrivate );
261 0 : return;
262 : }
263 0 : else if( eCurTok == DECLARE )
264 : {
265 0 : Next();
266 0 : DefDeclare( bPrivate );
267 0 : return;
268 : }
269 : // #i109049
270 0 : else if( eCurTok == TYPE )
271 : {
272 0 : Next();
273 0 : DefType( bPrivate );
274 0 : return;
275 : }
276 : }
277 :
278 : #ifdef SHARED
279 : #define tmpSHARED
280 : #undef SHARED
281 : #endif
282 : // SHARED were ignored
283 0 : if( Peek() == SHARED ) Next();
284 : #ifdef tmpSHARED
285 : #define SHARED
286 : #undef tmpSHARED
287 : #endif
288 : // PRESERVE only at REDIM
289 0 : if( Peek() == PRESERVE )
290 : {
291 0 : Next();
292 0 : if( eOp == _REDIM )
293 0 : eOp = _REDIMP;
294 : else
295 0 : Error( SbERR_UNEXPECTED, eCurTok );
296 : }
297 : SbiSymDef* pDef;
298 : SbiDimList* pDim;
299 :
300 : // #40689, Statics -> Modul-Initialising, skip in Sub
301 0 : sal_uInt32 nEndOfStaticLbl = 0;
302 0 : if( !bVBASupportOn && bStatic )
303 : {
304 0 : nEndOfStaticLbl = aGen.Gen( _JUMP, 0 );
305 0 : aGen.Statement(); // catch up on static here
306 : }
307 :
308 0 : bool bDefined = false;
309 0 : while( ( pDef = VarDecl( &pDim, bStatic, bConst ) ) != NULL )
310 : {
311 : /*fprintf(stderr, "Actual sub: \n");
312 : fprintf(stderr, "Symbol name: %s\n",OUStringToOString(pDef->GetName(),RTL_TEXTENCODING_UTF8).getStr());*/
313 0 : EnableErrors();
314 : // search variable:
315 0 : if( bSwitchPool )
316 0 : pPool = &aGlobals;
317 0 : SbiSymDef* pOld = pPool->Find( pDef->GetName() );
318 : // search also in the Runtime-Library
319 0 : bool bRtlSym = false;
320 0 : if( !pOld )
321 : {
322 0 : pOld = CheckRTLForSym( pDef->GetName(), SbxVARIANT );
323 0 : if( pOld )
324 0 : bRtlSym = true;
325 : }
326 0 : if( pOld && !(eOp == _REDIM || eOp == _REDIMP) )
327 : {
328 0 : if( pDef->GetScope() == SbLOCAL && pOld->GetScope() != SbLOCAL )
329 0 : pOld = NULL;
330 : }
331 0 : if( pOld )
332 : {
333 0 : bDefined = true;
334 : // always an error at a RTL-S
335 0 : if( !bRtlSym && (eOp == _REDIM || eOp == _REDIMP) )
336 : {
337 : // compare the attributes at a REDIM
338 : SbxDataType eDefType;
339 0 : bool bError_ = false;
340 0 : if( pOld->IsStatic() )
341 : {
342 0 : bError_ = true;
343 : }
344 0 : else if( pOld->GetType() != ( eDefType = pDef->GetType() ) )
345 : {
346 0 : if( !( eDefType == SbxVARIANT && !pDef->IsDefinedAs() ) )
347 0 : bError_ = true;
348 : }
349 0 : if( bError_ )
350 0 : Error( SbERR_VAR_DEFINED, pDef->GetName() );
351 : }
352 : else
353 0 : Error( SbERR_VAR_DEFINED, pDef->GetName() );
354 0 : delete pDef; pDef = pOld;
355 : }
356 : else
357 0 : pPool->Add( pDef );
358 :
359 : // #36374: Create the variable in front of the distinction IsNew()
360 : // Otherwise error at Dim Identifier As New Type and option explicit
361 0 : if( !bDefined && !(eOp == _REDIM || eOp == _REDIMP)
362 0 : && ( !bConst || pDef->GetScope() == SbGLOBAL ) )
363 : {
364 : // Declare variable or global constant
365 : SbiOpcode eOp2;
366 0 : switch ( pDef->GetScope() )
367 : {
368 0 : case SbGLOBAL: eOp2 = bPersistantGlobal ? _GLOBAL_P : _GLOBAL;
369 0 : goto global;
370 0 : case SbPUBLIC: eOp2 = bPersistantGlobal ? _PUBLIC_P : _PUBLIC;
371 : // #40689, no own Opcode anymore
372 0 : if( bVBASupportOn && bStatic )
373 : {
374 0 : eOp2 = _STATIC;
375 0 : break;
376 : }
377 0 : global: aGen.BackChain( nGblChain );
378 0 : nGblChain = 0;
379 0 : bGblDefs = bNewGblDefs = true;
380 0 : break;
381 0 : default: eOp2 = _LOCAL;
382 : }
383 0 : sal_uInt32 nOpnd2 = sal::static_int_cast< sal_uInt16 >( pDef->GetType() );
384 0 : if( pDef->IsWithEvents() )
385 0 : nOpnd2 |= SBX_TYPE_WITH_EVENTS_FLAG;
386 :
387 0 : if( bCompatible && pDef->IsNew() )
388 0 : nOpnd2 |= SBX_TYPE_DIM_AS_NEW_FLAG;
389 :
390 0 : short nFixedStringLength = pDef->GetFixedStringLength();
391 0 : if( nFixedStringLength >= 0 )
392 0 : nOpnd2 |= (SBX_FIXED_LEN_STRING_FLAG + (sal_uInt32(nFixedStringLength) << 17)); // len = all bits above 0x10000
393 :
394 0 : if( pDim != NULL && pDim->GetDims() > 0 )
395 0 : nOpnd2 |= SBX_TYPE_VAR_TO_DIM_FLAG;
396 :
397 0 : aGen.Gen( eOp2, pDef->GetId(), nOpnd2 );
398 : }
399 :
400 : // Initialising for self-defined daty types
401 : // and per NEW created variable
402 0 : if( pDef->GetType() == SbxOBJECT
403 0 : && pDef->GetTypeId() )
404 : {
405 0 : if( !bCompatible && !pDef->IsNew() )
406 : {
407 0 : OUString aTypeName( aGblStrings.Find( pDef->GetTypeId() ) );
408 0 : if( rTypeArray->Find( aTypeName, SbxCLASS_OBJECT ) == NULL )
409 : {
410 0 : if( CodeCompleteOptions::IsExtendedTypeDeclaration() )
411 : {
412 0 : if(!IsUnoInterface(aTypeName))
413 0 : Error( SbERR_UNDEF_TYPE, aTypeName );
414 : }
415 : else
416 0 : Error( SbERR_UNDEF_TYPE, aTypeName );
417 0 : }
418 : }
419 :
420 0 : if( bConst )
421 : {
422 0 : Error( SbERR_SYNTAX );
423 : }
424 :
425 0 : if( pDim )
426 : {
427 0 : if( eOp == _REDIMP )
428 : {
429 0 : SbiExpression aExpr( this, *pDef, NULL );
430 0 : aExpr.Gen();
431 0 : aGen.Gen( _REDIMP_ERASE );
432 :
433 0 : pDef->SetDims( pDim->GetDims() );
434 0 : SbiExpression aExpr2( this, *pDef, pDim );
435 0 : aExpr2.Gen();
436 0 : aGen.Gen( _DCREATE_REDIMP, pDef->GetId(), pDef->GetTypeId() );
437 : }
438 : else
439 : {
440 0 : pDef->SetDims( pDim->GetDims() );
441 0 : SbiExpression aExpr( this, *pDef, pDim );
442 0 : aExpr.Gen();
443 0 : aGen.Gen( _DCREATE, pDef->GetId(), pDef->GetTypeId() );
444 : }
445 : }
446 : else
447 : {
448 0 : SbiExpression aExpr( this, *pDef );
449 0 : aExpr.Gen();
450 0 : SbiOpcode eOp_ = pDef->IsNew() ? _CREATE : _TCREATE;
451 0 : aGen.Gen( eOp_, pDef->GetId(), pDef->GetTypeId() );
452 0 : if ( bVBASupportOn )
453 0 : aGen.Gen( _VBASET );
454 : else
455 0 : aGen.Gen( _SET );
456 : }
457 : }
458 : else
459 : {
460 0 : if( bConst )
461 : {
462 : // Definition of the constants
463 0 : if( pDim )
464 : {
465 0 : Error( SbERR_SYNTAX );
466 0 : delete pDim;
467 : }
468 0 : SbiExpression aVar( this, *pDef );
469 0 : if( !TestToken( EQ ) )
470 0 : goto MyBreak; // (see below)
471 0 : SbiConstExpression aExpr( this );
472 0 : if( !bDefined && aExpr.IsValid() )
473 : {
474 0 : if( pDef->GetScope() == SbGLOBAL )
475 : {
476 : // Create code only for the global constant!
477 0 : aVar.Gen();
478 0 : aExpr.Gen();
479 0 : aGen.Gen( _PUTC );
480 : }
481 0 : SbiConstDef* pConst = pDef->GetConstDef();
482 0 : if( aExpr.GetType() == SbxSTRING )
483 0 : pConst->Set( aExpr.GetString() );
484 : else
485 0 : pConst->Set( aExpr.GetValue(), aExpr.GetType() );
486 0 : }
487 : }
488 0 : else if( pDim )
489 : {
490 : // Dimension the variable
491 : // Delete the var at REDIM beforehand
492 0 : if( eOp == _REDIM )
493 : {
494 0 : SbiExpression aExpr( this, *pDef, NULL );
495 0 : aExpr.Gen();
496 0 : if ( bVBASupportOn )
497 : // delete the array but
498 : // clear the variable ( this
499 : // allows the processing of
500 : // the param to happen as normal without errors ( ordinary ERASE just clears the array )
501 0 : aGen.Gen( _ERASE_CLEAR );
502 : else
503 0 : aGen.Gen( _ERASE );
504 : }
505 0 : else if( eOp == _REDIMP )
506 : {
507 0 : SbiExpression aExpr( this, *pDef, NULL );
508 0 : aExpr.Gen();
509 0 : aGen.Gen( _REDIMP_ERASE );
510 : }
511 0 : pDef->SetDims( pDim->GetDims() );
512 0 : if( bPersistantGlobal )
513 0 : pDef->SetGlobal( true );
514 0 : SbiExpression aExpr( this, *pDef, pDim );
515 0 : aExpr.Gen();
516 0 : pDef->SetGlobal( false );
517 0 : aGen.Gen( (eOp == _STATIC) ? _DIM : eOp );
518 : }
519 : }
520 0 : if( !TestComma() )
521 0 : goto MyBreak;
522 :
523 : // Implementation of bSwitchPool (see above): pPool must not be set to &aGlobals
524 : // at the VarDecl-Call.
525 : // Apart from that the behavior should be absolutely identical,
526 : // i.e., pPool had to be reset always at the end of the loop.
527 : // also at a break
528 0 : pPool = pOldPool;
529 0 : continue; // Skip MyBreak
530 : MyBreak:
531 0 : pPool = pOldPool;
532 0 : break;
533 : }
534 :
535 : // #40689, finalize the jump over statics declarations
536 0 : if( !bVBASupportOn && bStatic )
537 : {
538 : // maintain the global chain
539 0 : nGblChain = aGen.Gen( _JUMP, 0 );
540 0 : bGblDefs = bNewGblDefs = true;
541 :
542 : // Register for Sub a jump to the end of statics
543 0 : aGen.BackChain( nEndOfStaticLbl );
544 : }
545 :
546 : }
547 :
548 : // Here were Arrays redimensioned.
549 :
550 0 : void SbiParser::ReDim()
551 : {
552 0 : DefVar( _REDIM, ( pProc && bVBASupportOn ) ? pProc->IsStatic() : false );
553 0 : }
554 :
555 : // ERASE array, ...
556 :
557 0 : void SbiParser::Erase()
558 : {
559 0 : while( !bAbort )
560 : {
561 0 : SbiExpression aExpr( this, SbLVALUE );
562 0 : aExpr.Gen();
563 0 : aGen.Gen( _ERASE );
564 0 : if( !TestComma() ) break;
565 0 : }
566 0 : }
567 :
568 : // Declaration of a data type
569 :
570 0 : void SbiParser::Type()
571 : {
572 0 : DefType( false );
573 0 : }
574 :
575 0 : void SbiParser::DefType( bool bPrivate )
576 : {
577 : // TODO: Use bPrivate
578 : (void)bPrivate;
579 :
580 : // Read the new Token lesen. It had to be a symbol
581 0 : if (!TestSymbol())
582 0 : return;
583 :
584 0 : if (rTypeArray->Find(aSym,SbxCLASS_OBJECT))
585 : {
586 0 : Error( SbERR_VAR_DEFINED, aSym );
587 0 : return;
588 : }
589 :
590 0 : SbxObject *pType = new SbxObject(aSym);
591 :
592 : SbiSymDef* pElem;
593 0 : SbiDimList* pDim = NULL;
594 0 : bool bDone = false;
595 :
596 0 : while( !bDone && !IsEof() )
597 : {
598 0 : switch( Peek() )
599 : {
600 : case ENDTYPE :
601 0 : pElem = NULL;
602 0 : bDone = true;
603 0 : Next();
604 0 : break;
605 :
606 : case EOLN :
607 : case REM :
608 0 : pElem = NULL;
609 0 : Next();
610 0 : break;
611 :
612 : default:
613 0 : pElem = VarDecl(&pDim, false, false);
614 0 : if( !pElem )
615 0 : bDone = true; // Error occurred
616 : }
617 0 : if( pElem )
618 : {
619 0 : SbxArray *pTypeMembers = pType->GetProperties();
620 0 : OUString aElemName = pElem->GetName();
621 0 : if( pTypeMembers->Find( aElemName, SbxCLASS_DONTCARE) )
622 : {
623 0 : Error (SbERR_VAR_DEFINED);
624 : }
625 : else
626 : {
627 0 : SbxDataType eElemType = pElem->GetType();
628 0 : SbxProperty *pTypeElem = new SbxProperty( aElemName, eElemType );
629 0 : if( pDim )
630 : {
631 0 : SbxDimArray* pArray = new SbxDimArray( pElem->GetType() );
632 0 : if ( pDim->GetSize() )
633 : {
634 : // Dimension the target array
635 :
636 0 : for ( short i=0; i<pDim->GetSize();++i )
637 : {
638 0 : sal_Int32 lb = nBase;
639 0 : SbiExprNode* pNode = pDim->Get(i)->GetExprNode();
640 0 : sal_Int32 ub = pNode->GetNumber();
641 0 : if ( !pDim->Get( i )->IsBased() ) // each dim is low/up
642 : {
643 0 : if ( ++i >= pDim->GetSize() ) // trouble
644 0 : StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
645 0 : pNode = pDim->Get(i)->GetExprNode();
646 0 : lb = ub;
647 0 : ub = pNode->GetNumber();
648 : }
649 0 : else if ( !bCompatible )
650 0 : ub += nBase;
651 0 : pArray->AddDim32( lb, ub );
652 : }
653 0 : pArray->setHasFixedSize( true );
654 : }
655 : else
656 0 : pArray->unoAddDim( 0, -1 ); // variant array
657 0 : sal_uInt16 nSavFlags = pTypeElem->GetFlags();
658 : // need to reset the FIXED flag
659 : // when calling PutObject ( because the type will not match Object )
660 0 : pTypeElem->ResetFlag( SBX_FIXED );
661 0 : pTypeElem->PutObject( pArray );
662 0 : pTypeElem->SetFlags( nSavFlags );
663 : }
664 : // Nested user type?
665 0 : if( eElemType == SbxOBJECT )
666 : {
667 0 : sal_uInt16 nElemTypeId = pElem->GetTypeId();
668 0 : if( nElemTypeId != 0 )
669 : {
670 0 : OUString aTypeName( aGblStrings.Find( nElemTypeId ) );
671 0 : SbxObject* pTypeObj = static_cast< SbxObject* >( rTypeArray->Find( aTypeName, SbxCLASS_OBJECT ) );
672 0 : if( pTypeObj != NULL )
673 : {
674 0 : SbxObject* pCloneObj = cloneTypeObjectImpl( *pTypeObj );
675 0 : pTypeElem->PutObject( pCloneObj );
676 0 : }
677 : }
678 : }
679 0 : pTypeMembers->Insert( pTypeElem, pTypeMembers->Count() );
680 : }
681 0 : delete pDim, pDim = NULL;
682 0 : delete pElem;
683 : }
684 : }
685 :
686 0 : pType->Remove( OUString("Name"), SbxCLASS_DONTCARE );
687 0 : pType->Remove( OUString("Parent"), SbxCLASS_DONTCARE );
688 :
689 0 : rTypeArray->Insert (pType,rTypeArray->Count());
690 : }
691 :
692 :
693 : // Declaration of Enum type
694 :
695 0 : void SbiParser::Enum()
696 : {
697 0 : DefEnum( false );
698 0 : }
699 :
700 0 : void SbiParser::DefEnum( bool bPrivate )
701 : {
702 : // Read a the new Token. It had to be a symbol
703 0 : if (!TestSymbol())
704 0 : return;
705 :
706 0 : OUString aEnumName = aSym;
707 0 : if( rEnumArray->Find(aEnumName,SbxCLASS_OBJECT) )
708 : {
709 0 : Error( SbERR_VAR_DEFINED, aSym );
710 0 : return;
711 : }
712 :
713 0 : SbxObject *pEnum = new SbxObject( aEnumName );
714 0 : if( bPrivate )
715 : {
716 0 : pEnum->SetFlag( SBX_PRIVATE );
717 : }
718 : SbiSymDef* pElem;
719 : SbiDimList* pDim;
720 0 : bool bDone = false;
721 :
722 : // Starting with -1 to make first default value 0 after ++
723 0 : sal_Int32 nCurrentEnumValue = -1;
724 0 : while( !bDone && !IsEof() )
725 : {
726 0 : switch( Peek() )
727 : {
728 : case ENDENUM :
729 0 : pElem = NULL;
730 0 : bDone = true;
731 0 : Next();
732 0 : break;
733 :
734 : case EOLN :
735 : case REM :
736 0 : pElem = NULL;
737 0 : Next();
738 0 : break;
739 :
740 : default:
741 : {
742 : // TODO: Check existing!
743 0 : bool bDefined = false;
744 :
745 0 : pDim = NULL;
746 0 : pElem = VarDecl( &pDim, false, true );
747 0 : if( !pElem )
748 : {
749 0 : bDone = true; // Error occurred
750 0 : break;
751 : }
752 0 : else if( pDim )
753 : {
754 0 : delete pDim;
755 0 : Error( SbERR_SYNTAX );
756 0 : bDone = true; // Error occurred
757 0 : break;
758 : }
759 :
760 0 : SbiExpression aVar( this, *pElem );
761 0 : if( Peek() == EQ )
762 : {
763 0 : Next();
764 :
765 0 : SbiConstExpression aExpr( this );
766 0 : if( !bDefined && aExpr.IsValid() )
767 : {
768 0 : SbxVariableRef xConvertVar = new SbxVariable();
769 0 : if( aExpr.GetType() == SbxSTRING )
770 0 : xConvertVar->PutString( aExpr.GetString() );
771 : else
772 0 : xConvertVar->PutDouble( aExpr.GetValue() );
773 :
774 0 : nCurrentEnumValue = xConvertVar->GetLong();
775 0 : }
776 : }
777 : else
778 0 : nCurrentEnumValue++;
779 :
780 0 : SbiSymPool* pPoolToUse = bPrivate ? pPool : &aGlobals;
781 :
782 0 : SbiSymDef* pOld = pPoolToUse->Find( pElem->GetName() );
783 0 : if( pOld )
784 : {
785 0 : Error( SbERR_VAR_DEFINED, pElem->GetName() );
786 0 : bDone = true; // Error occurred
787 0 : break;
788 : }
789 :
790 0 : pPool->Add( pElem );
791 :
792 0 : if( !bPrivate )
793 : {
794 0 : SbiOpcode eOp = _GLOBAL;
795 0 : aGen.BackChain( nGblChain );
796 0 : nGblChain = 0;
797 0 : bGblDefs = bNewGblDefs = true;
798 : aGen.Gen(
799 0 : eOp, pElem->GetId(),
800 0 : sal::static_int_cast< sal_uInt16 >( pElem->GetType() ) );
801 :
802 0 : aVar.Gen();
803 0 : sal_uInt16 nStringId = aGen.GetParser()->aGblStrings.Add( nCurrentEnumValue, SbxLONG );
804 0 : aGen.Gen( _NUMBER, nStringId );
805 0 : aGen.Gen( _PUTC );
806 : }
807 :
808 0 : SbiConstDef* pConst = pElem->GetConstDef();
809 0 : pConst->Set( nCurrentEnumValue, SbxLONG );
810 : }
811 : }
812 0 : if( pElem )
813 : {
814 0 : SbxArray *pEnumMembers = pEnum->GetProperties();
815 0 : SbxProperty *pEnumElem = new SbxProperty( pElem->GetName(), SbxLONG );
816 0 : pEnumElem->PutLong( nCurrentEnumValue );
817 0 : pEnumElem->ResetFlag( SBX_WRITE );
818 0 : pEnumElem->SetFlag( SBX_CONST );
819 0 : pEnumMembers->Insert( pEnumElem, pEnumMembers->Count() );
820 : }
821 : }
822 :
823 0 : pEnum->Remove( OUString("Name"), SbxCLASS_DONTCARE );
824 0 : pEnum->Remove( OUString("Parent"), SbxCLASS_DONTCARE );
825 :
826 0 : rEnumArray->Insert( pEnum, rEnumArray->Count() );
827 : }
828 :
829 :
830 : // Procedure-Declaration
831 : // the first Token is already read in (SUB/FUNCTION)
832 : // xxx Name [LIB "name"[ALIAS "name"]][(Parameter)][AS TYPE]
833 :
834 0 : SbiProcDef* SbiParser::ProcDecl( bool bDecl )
835 : {
836 0 : bool bFunc = ( eCurTok == FUNCTION );
837 0 : bool bProp = ( eCurTok == GET || eCurTok == SET || eCurTok == LET );
838 0 : if( !TestSymbol() ) return NULL;
839 0 : OUString aName( aSym );
840 0 : SbxDataType eType = eScanType;
841 0 : SbiProcDef* pDef = new SbiProcDef( this, aName, true );
842 0 : pDef->SetType( eType );
843 0 : if( Peek() == _CDECL_ )
844 : {
845 0 : Next(); pDef->SetCdecl();
846 : }
847 0 : if( Peek() == LIB )
848 : {
849 0 : Next();
850 0 : if( Next() == FIXSTRING )
851 : {
852 0 : pDef->GetLib() = aSym;
853 : }
854 : else
855 : {
856 0 : Error( SbERR_SYNTAX );
857 : }
858 : }
859 0 : if( Peek() == ALIAS )
860 : {
861 0 : Next();
862 0 : if( Next() == FIXSTRING )
863 : {
864 0 : pDef->GetAlias() = aSym;
865 : }
866 : else
867 : {
868 0 : Error( SbERR_SYNTAX );
869 : }
870 : }
871 0 : if( !bDecl )
872 : {
873 : // CDECL, LIB and ALIAS are invalid
874 0 : if( !pDef->GetLib().isEmpty() )
875 : {
876 0 : Error( SbERR_UNEXPECTED, LIB );
877 : }
878 0 : if( !pDef->GetAlias().isEmpty() )
879 : {
880 0 : Error( SbERR_UNEXPECTED, ALIAS );
881 : }
882 0 : if( pDef->IsCdecl() )
883 : {
884 0 : Error( SbERR_UNEXPECTED, _CDECL_ );
885 : }
886 0 : pDef->SetCdecl( false );
887 0 : pDef->GetLib() = "";
888 0 : pDef->GetAlias() = "";
889 : }
890 0 : else if( pDef->GetLib().isEmpty() )
891 : {
892 : // ALIAS and CDECL only together with LIB
893 0 : if( !pDef->GetAlias().isEmpty() )
894 : {
895 0 : Error( SbERR_UNEXPECTED, ALIAS );
896 : }
897 0 : if( pDef->IsCdecl() )
898 : {
899 0 : Error( SbERR_UNEXPECTED, _CDECL_ );
900 : }
901 0 : pDef->SetCdecl( false );
902 0 : pDef->GetAlias() = "";
903 : }
904 : // Brackets?
905 0 : if( Peek() == LPAREN )
906 : {
907 0 : Next();
908 0 : if( Peek() == RPAREN )
909 : {
910 0 : Next();
911 : }
912 : else
913 : {
914 : for(;;)
915 : {
916 0 : bool bByVal = false;
917 0 : bool bOptional = false;
918 0 : bool bParamArray = false;
919 0 : while( Peek() == BYVAL || Peek() == BYREF || Peek() == _OPTIONAL_ )
920 : {
921 0 : if( Peek() == BYVAL )
922 : {
923 0 : bByVal = true;
924 : }
925 0 : else if ( Peek() == BYREF )
926 : {
927 0 : bByVal = false;
928 : }
929 0 : else if ( Peek() == _OPTIONAL_ )
930 : {
931 0 : bOptional = true;
932 : }
933 0 : Next();
934 : }
935 0 : if( bCompatible && Peek() == PARAMARRAY )
936 : {
937 0 : if( bByVal || bOptional )
938 : {
939 0 : Error( SbERR_UNEXPECTED, PARAMARRAY );
940 : }
941 0 : Next();
942 0 : bParamArray = true;
943 : }
944 0 : SbiSymDef* pPar = VarDecl( NULL, false, false );
945 0 : if( !pPar )
946 : {
947 0 : break;
948 : }
949 0 : if( bByVal )
950 : {
951 0 : pPar->SetByVal();
952 : }
953 0 : if( bOptional )
954 : {
955 0 : pPar->SetOptional();
956 : }
957 0 : if( bParamArray )
958 : {
959 0 : pPar->SetParamArray();
960 : }
961 0 : pDef->GetParams().Add( pPar );
962 0 : SbiToken eTok = Next();
963 0 : if( eTok != COMMA && eTok != RPAREN )
964 : {
965 0 : bool bError2 = true;
966 0 : if( bOptional && bCompatible && eTok == EQ )
967 : {
968 0 : SbiConstExpression* pDefaultExpr = new SbiConstExpression( this );
969 0 : SbxDataType eType2 = pDefaultExpr->GetType();
970 :
971 : sal_uInt16 nStringId;
972 0 : if( eType2 == SbxSTRING )
973 : {
974 0 : nStringId = aGblStrings.Add( pDefaultExpr->GetString() );
975 : }
976 : else
977 : {
978 0 : nStringId = aGblStrings.Add( pDefaultExpr->GetValue(), eType2 );
979 : }
980 0 : pPar->SetDefaultId( nStringId );
981 0 : delete pDefaultExpr;
982 :
983 0 : eTok = Next();
984 0 : if( eTok == COMMA || eTok == RPAREN )
985 : {
986 0 : bError2 = false;
987 : }
988 : }
989 0 : if( bError2 )
990 : {
991 0 : Error( SbERR_EXPECTED, RPAREN );
992 0 : break;
993 : }
994 : }
995 0 : if( eTok == RPAREN )
996 : {
997 0 : break;
998 : }
999 0 : }
1000 : }
1001 : }
1002 0 : TypeDecl( *pDef );
1003 0 : if( eType != SbxVARIANT && pDef->GetType() != eType )
1004 : {
1005 0 : Error( SbERR_BAD_DECLARATION, aName );
1006 : }
1007 0 : if( pDef->GetType() == SbxVARIANT && !( bFunc || bProp ) )
1008 : {
1009 0 : pDef->SetType( SbxEMPTY );
1010 : }
1011 0 : return pDef;
1012 : }
1013 :
1014 : // DECLARE
1015 :
1016 0 : void SbiParser::Declare()
1017 : {
1018 0 : DefDeclare( false );
1019 0 : }
1020 :
1021 0 : void SbiParser::DefDeclare( bool bPrivate )
1022 : {
1023 0 : Next();
1024 0 : if( eCurTok != SUB && eCurTok != FUNCTION )
1025 : {
1026 0 : Error( SbERR_UNEXPECTED, eCurTok );
1027 : }
1028 : else
1029 : {
1030 0 : bool bFunction = (eCurTok == FUNCTION);
1031 :
1032 0 : SbiProcDef* pDef = ProcDecl( true );
1033 0 : if( pDef )
1034 : {
1035 0 : if( pDef->GetLib().isEmpty() )
1036 : {
1037 0 : Error( SbERR_EXPECTED, LIB );
1038 : }
1039 : // Is it already there?
1040 0 : SbiSymDef* pOld = aPublics.Find( pDef->GetName() );
1041 0 : if( pOld )
1042 : {
1043 0 : SbiProcDef* p = pOld->GetProcDef();
1044 0 : if( !p )
1045 : {
1046 : // Declared as a variable
1047 0 : Error( SbERR_BAD_DECLARATION, pDef->GetName() );
1048 0 : delete pDef;
1049 0 : pDef = NULL;
1050 : }
1051 : else
1052 : {
1053 0 : pDef->Match( p );
1054 : }
1055 : }
1056 : else
1057 : {
1058 0 : aPublics.Add( pDef );
1059 : }
1060 0 : if ( pDef )
1061 : {
1062 0 : pDef->SetPublic( !bPrivate );
1063 :
1064 : // New declare handling
1065 0 : if( !pDef->GetLib().isEmpty())
1066 : {
1067 0 : if( bNewGblDefs && nGblChain == 0 )
1068 : {
1069 0 : nGblChain = aGen.Gen( _JUMP, 0 );
1070 0 : bNewGblDefs = false;
1071 : }
1072 :
1073 0 : sal_uInt16 nSavLine = nLine;
1074 0 : aGen.Statement();
1075 0 : pDef->Define();
1076 0 : pDef->SetLine1( nSavLine );
1077 0 : pDef->SetLine2( nSavLine );
1078 :
1079 0 : SbiSymPool& rPool = pDef->GetParams();
1080 0 : sal_uInt16 nParCount = rPool.GetSize();
1081 :
1082 0 : SbxDataType eType = pDef->GetType();
1083 0 : if( bFunction )
1084 : {
1085 0 : aGen.Gen( _PARAM, 0, sal::static_int_cast< sal_uInt16 >( eType ) );
1086 : }
1087 0 : if( nParCount > 1 )
1088 : {
1089 0 : aGen.Gen( _ARGC );
1090 :
1091 0 : for( sal_uInt16 i = 1 ; i < nParCount ; ++i )
1092 : {
1093 0 : SbiSymDef* pParDef = rPool.Get( i );
1094 0 : SbxDataType eParType = pParDef->GetType();
1095 :
1096 0 : aGen.Gen( _PARAM, i, sal::static_int_cast< sal_uInt16 >( eParType ) );
1097 0 : aGen.Gen( _ARGV );
1098 :
1099 0 : sal_uInt16 nTyp = sal::static_int_cast< sal_uInt16 >( pParDef->GetType() );
1100 0 : if( pParDef->IsByVal() )
1101 : {
1102 : // Reset to avoid additional byval in call to wrapper function
1103 0 : pParDef->SetByVal( false );
1104 0 : nTyp |= 0x8000;
1105 : }
1106 0 : aGen.Gen( _ARGTYP, nTyp );
1107 : }
1108 : }
1109 :
1110 0 : aGen.Gen( _LIB, aGblStrings.Add( pDef->GetLib() ) );
1111 :
1112 0 : SbiOpcode eOp = pDef->IsCdecl() ? _CALLC : _CALL;
1113 0 : sal_uInt16 nId = pDef->GetId();
1114 0 : if( !pDef->GetAlias().isEmpty() )
1115 : {
1116 0 : nId = ( nId & 0x8000 ) | aGblStrings.Add( pDef->GetAlias() );
1117 : }
1118 0 : if( nParCount > 1 )
1119 : {
1120 0 : nId |= 0x8000;
1121 : }
1122 0 : aGen.Gen( eOp, nId, sal::static_int_cast< sal_uInt16 >( eType ) );
1123 :
1124 0 : if( bFunction )
1125 : {
1126 0 : aGen.Gen( _PUT );
1127 : }
1128 0 : aGen.Gen( _LEAVE );
1129 : }
1130 : }
1131 : }
1132 : }
1133 0 : }
1134 :
1135 0 : void SbiParser::Attribute()
1136 : {
1137 : // TODO: Need to implement the method as an attributed object.
1138 0 : while( Next() != EQ )
1139 : {
1140 0 : if( Next() != DOT)
1141 : {
1142 0 : break;
1143 : }
1144 : }
1145 :
1146 0 : if( eCurTok != EQ )
1147 : {
1148 0 : Error( SbERR_SYNTAX );
1149 : }
1150 : else
1151 : {
1152 0 : SbiExpression aValue( this );
1153 : }
1154 : // Don't generate any code - just discard it.
1155 0 : }
1156 :
1157 : // Call of a SUB or a FUNCTION
1158 :
1159 0 : void SbiParser::Call()
1160 : {
1161 0 : SbiExpression aVar( this, SbSYMBOL );
1162 0 : aVar.Gen( FORCE_CALL );
1163 0 : aGen.Gen( _GET );
1164 0 : }
1165 :
1166 : // SUB/FUNCTION
1167 :
1168 0 : void SbiParser::SubFunc()
1169 : {
1170 0 : DefProc( false, false );
1171 0 : }
1172 :
1173 : // Read in of a procedure
1174 :
1175 0 : void SbiParser::DefProc( bool bStatic, bool bPrivate )
1176 : {
1177 0 : sal_uInt16 l1 = nLine, l2 = nLine;
1178 0 : bool bSub = ( eCurTok == SUB );
1179 0 : bool bProperty = ( eCurTok == PROPERTY );
1180 0 : PropertyMode ePropertyMode = PROPERTY_MODE_NONE;
1181 0 : if( bProperty )
1182 : {
1183 0 : Next();
1184 0 : if( eCurTok == GET )
1185 : {
1186 0 : ePropertyMode = PROPERTY_MODE_GET;
1187 : }
1188 0 : else if( eCurTok == LET )
1189 : {
1190 0 : ePropertyMode = PROPERTY_MODE_LET;
1191 : }
1192 0 : else if( eCurTok == SET )
1193 : {
1194 0 : ePropertyMode = PROPERTY_MODE_SET;
1195 : }
1196 : else
1197 : {
1198 0 : Error( SbERR_EXPECTED, "Get or Let or Set" );
1199 : }
1200 : }
1201 :
1202 0 : SbiToken eExit = eCurTok;
1203 0 : SbiProcDef* pDef = ProcDecl( false );
1204 0 : if( !pDef )
1205 : {
1206 0 : return;
1207 : }
1208 0 : pDef->setPropertyMode( ePropertyMode );
1209 :
1210 : // Is the Proc already declared?
1211 0 : SbiSymDef* pOld = aPublics.Find( pDef->GetName() );
1212 0 : if( pOld )
1213 : {
1214 0 : bool bError_ = false;
1215 :
1216 0 : pProc = pOld->GetProcDef();
1217 0 : if( !pProc )
1218 : {
1219 : // Declared as a variable
1220 0 : Error( SbERR_BAD_DECLARATION, pDef->GetName() );
1221 0 : delete pDef;
1222 0 : pProc = NULL;
1223 0 : bError_ = true;
1224 : }
1225 : // #100027: Multiple declaration -> Error
1226 : // #112787: Not for setup, REMOVE for 8
1227 0 : else if( pProc->IsUsedForProcDecl() )
1228 : {
1229 0 : PropertyMode ePropMode = pDef->getPropertyMode();
1230 0 : if( ePropMode == PROPERTY_MODE_NONE || ePropMode == pProc->getPropertyMode() )
1231 : {
1232 0 : Error( SbERR_PROC_DEFINED, pDef->GetName() );
1233 0 : delete pDef;
1234 0 : pProc = NULL;
1235 0 : bError_ = true;
1236 : }
1237 : }
1238 :
1239 0 : if( !bError_ )
1240 : {
1241 0 : pDef->Match( pProc );
1242 0 : pProc = pDef;
1243 : }
1244 : }
1245 : else
1246 : {
1247 0 : aPublics.Add( pDef ), pProc = pDef;
1248 : }
1249 0 : if( !pProc )
1250 : {
1251 0 : return;
1252 : }
1253 0 : pProc->SetPublic( !bPrivate );
1254 :
1255 : // Now we set the search hierarchy for symbols as well as the
1256 : // current procedure.
1257 0 : aPublics.SetProcId( pProc->GetId() );
1258 0 : pProc->GetParams().SetParent( &aPublics );
1259 0 : if( bStatic )
1260 : {
1261 0 : if ( bVBASupportOn )
1262 : {
1263 0 : pProc->SetStatic( true );
1264 : }
1265 : else
1266 : {
1267 0 : Error( SbERR_NOT_IMPLEMENTED ); // STATIC SUB ...
1268 : }
1269 : }
1270 : else
1271 : {
1272 0 : pProc->SetStatic( false );
1273 : }
1274 : // Normal case: Local variable->parameter->global variable
1275 0 : pProc->GetLocals().SetParent( &pProc->GetParams() );
1276 0 : pPool = &pProc->GetLocals();
1277 :
1278 0 : pProc->Define();
1279 0 : OpenBlock( eExit );
1280 0 : StmntBlock( bSub ? ENDSUB : (bProperty ? ENDPROPERTY : ENDFUNC) );
1281 0 : l2 = nLine;
1282 0 : pProc->SetLine1( l1 );
1283 0 : pProc->SetLine2( l2 );
1284 0 : pPool = &aPublics;
1285 0 : aPublics.SetProcId( 0 );
1286 : // Open labels?
1287 0 : pProc->GetLabels().CheckRefs();
1288 0 : CloseBlock();
1289 0 : aGen.Gen( _LEAVE );
1290 0 : pProc = NULL;
1291 : }
1292 :
1293 : // STATIC variable|procedure
1294 :
1295 0 : void SbiParser::Static()
1296 : {
1297 0 : DefStatic( false );
1298 0 : }
1299 :
1300 0 : void SbiParser::DefStatic( bool bPrivate )
1301 : {
1302 : SbiSymPool* p;
1303 :
1304 0 : switch( Peek() )
1305 : {
1306 : case SUB:
1307 : case FUNCTION:
1308 : case PROPERTY:
1309 : // End global chain if necessary (not done in
1310 : // SbiParser::Parse() under these conditions
1311 0 : if( bNewGblDefs && nGblChain == 0 )
1312 : {
1313 0 : nGblChain = aGen.Gen( _JUMP, 0 );
1314 0 : bNewGblDefs = false;
1315 : }
1316 0 : Next();
1317 0 : DefProc( true, bPrivate );
1318 0 : break;
1319 : default:
1320 0 : if( !pProc )
1321 : {
1322 0 : Error( SbERR_NOT_IN_SUBR );
1323 : }
1324 : // Reset the Pool, so that STATIC-Declarations go into the
1325 : // global Pool
1326 0 : p = pPool;
1327 0 : pPool = &aPublics;
1328 0 : DefVar( _STATIC, true );
1329 0 : pPool = p;
1330 0 : break;
1331 : }
1332 0 : }
1333 :
1334 0 : bool SbiParser::IsUnoInterface(const OUString& sTypeName)
1335 : {
1336 : try
1337 : {
1338 : return css::reflection::theCoreReflection::get(
1339 0 : comphelper::getProcessComponentContext())->forName(sTypeName).is();
1340 : }
1341 0 : catch(const Exception&)
1342 : {
1343 : OSL_FAIL("Could not create reflection.CoreReflection.");
1344 : }
1345 0 : return false;
1346 : }
1347 :
1348 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|