<s> package org . eclipse . jdt . internal . eval ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . core . compiler . IProblem ; import org . eclipse . jdt . internal . compiler . CompilationResult ; import org . eclipse . jdt . internal . compiler . ast . * ; import org . eclipse . jdt . internal . compiler . lookup . Binding ; import org . eclipse . jdt . internal . compiler . parser . Parser ; import org . eclipse . jdt . internal . compiler . problem . ProblemReporter ; public class CodeSnippetParser extends Parser implements EvaluationConstants { int codeSnippetStart , codeSnippetEnd ; EvaluationContext evaluationContext ; boolean hasRecoveredOnExpression ; int lastStatement = - 1 ; int lineSeparatorLength ; int problemCountBeforeRecovery = 0 ; public CodeSnippetParser ( ProblemReporter problemReporter , EvaluationContext evaluationContext , boolean optimizeStringLiterals , int codeSnippetStart , int codeSnippetEnd ) { super ( problemReporter , optimizeStringLiterals ) ; this . codeSnippetStart = codeSnippetStart ; this . codeSnippetEnd = codeSnippetEnd ; this . evaluationContext = evaluationContext ; this . reportOnlyOneSyntaxError = true ; this . javadocParser . checkDocComment = false ; } protected void classInstanceCreation ( boolean alwaysQualified ) { AllocationExpression alloc ; int length ; if ( ( ( length = this . astLengthStack [ this . astLengthPtr -- ] ) == 1 ) && ( this . astStack [ this . astPtr ] == null ) ) { this . astPtr -- ; if ( alwaysQualified ) { alloc = new QualifiedAllocationExpression ( ) ; } else { alloc = new CodeSnippetAllocationExpression ( this . evaluationContext ) ; } alloc . sourceEnd = this . endPosition ; if ( ( length = this . expressionLengthStack [ this . expressionLengthPtr -- ] ) != 0 ) { this . expressionPtr -= length ; System . arraycopy ( this . expressionStack , this . expressionPtr + 1 , alloc . arguments = new Expression [ length ] , 0 , length ) ; } alloc . type = getTypeReference ( 0 ) ; checkForDiamond ( alloc . type ) ; alloc . sourceStart = this . intStack [ this . intPtr -- ] ; pushOnExpressionStack ( alloc ) ; } else { dispatchDeclarationInto ( length ) ; TypeDeclaration anonymousTypeDeclaration = ( TypeDeclaration ) this . astStack [ this . astPtr ] ; anonymousTypeDeclaration . declarationSourceEnd = this . endStatementPosition ; if ( anonymousTypeDeclaration . allocation != null ) { anonymousTypeDeclaration . allocation . sourceEnd = this . endStatementPosition ; } this . astPtr -- ; this . astLengthPtr -- ; } } protected void consumeClassInstanceCreationExpressionWithTypeArguments ( ) { AllocationExpression alloc ; int length ; if ( ( ( length = this . astLengthStack [ this . astLengthPtr -- ] ) == 1 ) && ( this . astStack [ this . astPtr ] == null ) ) { this . astPtr -- ; alloc = new CodeSnippetAllocationExpression ( this . evaluationContext ) ; alloc . sourceEnd = this . endPosition ; if ( ( length = this . expressionLengthStack [ this . expressionLengthPtr -- ] ) != 0 ) { this . expressionPtr -= length ; System . arraycopy ( this . expressionStack , this . expressionPtr + 1 , alloc . arguments = new Expression [ length ] , 0 , length ) ; } alloc . type = getTypeReference ( 0 ) ; length = this . genericsLengthStack [ this . genericsLengthPtr -- ] ; this . genericsPtr -= length ; System . arraycopy ( this . genericsStack , this . genericsPtr + 1 , alloc . typeArguments = new TypeReference [ length ] , 0 , length ) ; this . intPtr -- ; alloc . sourceStart = this . intStack [ this . intPtr -- ] ; pushOnExpressionStack ( alloc ) ; } else { dispatchDeclarationInto ( length ) ; TypeDeclaration anonymousTypeDeclaration = ( TypeDeclaration ) this . astStack [ this . astPtr ] ; anonymousTypeDeclaration . declarationSourceEnd = this . endStatementPosition ; anonymousTypeDeclaration . bodyEnd = this . endStatementPosition ; if ( length == 0 && ! containsComment ( anonymousTypeDeclaration . bodyStart , anonymousTypeDeclaration . bodyEnd ) ) { anonymousTypeDeclaration . bits |= ASTNode . UndocumentedEmptyBlock ; } this . astPtr -- ; this . astLengthPtr -- ; QualifiedAllocationExpression allocationExpression = anonymousTypeDeclaration . allocation ; if ( allocationExpression != null ) { allocationExpression . sourceEnd = this . endStatementPosition ; length = this . genericsLengthStack [ this . genericsLengthPtr -- ] ; this . genericsPtr -= length ; System . arraycopy ( this . genericsStack , this . genericsPtr + 1 , allocationExpression . typeArguments = new TypeReference [ length ] , 0 , length ) ; allocationExpression . sourceStart = this . intStack [ this . intPtr -- ] ; } } } protected void consumeClassDeclaration ( ) { super . consumeClassDeclaration ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeClassHeaderName1 ( ) { TypeDeclaration typeDecl ; if ( this . nestedMethod [ this . nestedType ] == 0 ) { if ( this . nestedType != 0 ) { typeDecl = new TypeDeclaration ( this . compilationUnit . compilationResult ) ; typeDecl . bits |= ASTNode . IsMemberType ; } else { typeDecl = new CodeSnippetTypeDeclaration ( this . compilationUnit . compilationResult ) ; } } else { typeDecl = new TypeDeclaration ( this . compilationUnit . compilationResult ) ; typeDecl . bits |= ASTNode . IsLocalType ; markEnclosingMemberWithLocalType ( ) ; blockReal ( ) ; } long pos = this . identifierPositionStack [ this . identifierPtr ] ; typeDecl . sourceEnd = ( int ) pos ; typeDecl . sourceStart = ( int ) ( pos >>> 32 ) ; typeDecl . name = this . identifierStack [ this . identifierPtr -- ] ; this . identifierLengthPtr -- ; typeDecl . declarationSourceStart = this . intStack [ this . intPtr -- ] ; this . intPtr -- ; typeDecl . modifiersSourceStart = this . intStack [ this . intPtr -- ] ; typeDecl . modifiers = this . intStack [ this . intPtr -- ] ; if ( typeDecl . modifiersSourceStart >= 0 ) { typeDecl . declarationSourceStart = typeDecl . modifiersSourceStart ; } typeDecl . bodyStart = typeDecl . sourceEnd + 1 ; pushOnAstStack ( typeDecl ) ; this . listLength = 0 ; if ( this . currentElement != null ) { this . lastCheckPoint = typeDecl . bodyStart ; this . currentElement = this . currentElement . add ( typeDecl , 0 ) ; this . lastIgnoredToken = - 1 ; } typeDecl . javadoc = this . javadoc ; this . javadoc = null ; } protected void consumeEmptyStatement ( ) { super . consumeEmptyStatement ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeEnhancedForStatement ( ) { super . consumeEnhancedForStatement ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeExpressionStatement ( ) { super . consumeExpressionStatement ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeFieldAccess ( boolean isSuperAccess ) { FieldReference fr = new CodeSnippetFieldReference ( this . identifierStack [ this . identifierPtr ] , this . identifierPositionStack [ this . identifierPtr -- ] , this . evaluationContext ) ; this . identifierLengthPtr -- ; if ( isSuperAccess ) { fr . sourceStart = this . intStack [ this . intPtr -- ] ; problemReporter ( ) . codeSnippetMissingClass ( null , 0 , 0 ) ; fr . receiver = new CodeSnippetSuperReference ( fr . sourceStart , this . endPosition ) ; pushOnExpressionStack ( fr ) ; } else { if ( ( fr . receiver = this . expressionStack [ this . expressionPtr ] ) . isThis ( ) ) { fr . sourceStart = fr . receiver . sourceStart ; } this . expressionStack [ this . expressionPtr ] = fr ; } } protected void consumeInternalCompilationUnit ( ) { } protected void consumeInternalCompilationUnitWithTypes ( ) { int length ; if ( ( length = this . astLengthStack [ this . astLengthPtr -- ] ) != 0 ) { this . compilationUnit . types = new TypeDeclaration [ length ] ; this . astPtr -= length ; System . arraycopy ( this . astStack , this . astPtr + 1 , this . compilationUnit . types , 0 , length ) ; } } protected void consumeLocalVariableDeclarationStatement ( ) { super . consumeLocalVariableDeclarationStatement ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeMethodDeclaration ( boolean isNotAbstract ) { super . consumeMethodDeclaration ( isNotAbstract ) ; MethodDeclaration methodDecl = ( MethodDeclaration ) this . astStack [ this . astPtr ] ; if ( isTopLevelType ( ) ) { int last = methodDecl . statements == null ? - 1 : methodDecl . statements . length - 1 ; if ( last >= 0 && methodDecl . statements [ last ] instanceof Expression ) { Expression lastExpression = ( Expression ) methodDecl . statements [ last ] ; methodDecl . statements [ last ] = new CodeSnippetReturnStatement ( lastExpression , lastExpression . sourceStart , lastExpression . sourceEnd ) ; } } int start = methodDecl . bodyStart - 1 , end = start ; long position = ( ( long ) start << 32 ) + end ; long [ ] positions = new long [ ] { position } ; if ( this . evaluationContext . localVariableNames != null ) { int varCount = this . evaluationContext . localVariableNames . length ; Statement [ ] newStatements = new Statement [ varCount + 1 ] ; for ( int i = 0 ; i < varCount ; i ++ ) { char [ ] trimmedTypeName = this . evaluationContext . localVariableTypeNames [ i ] ; int nameEnd = CharOperation . indexOf ( '[' , trimmedTypeName ) ; if ( nameEnd >= 0 ) { trimmedTypeName = CharOperation . subarray ( trimmedTypeName , 0 , nameEnd ) ; } nameEnd = CharOperation . indexOf ( ' ' , trimmedTypeName ) ; if ( nameEnd >= 0 ) { trimmedTypeName = CharOperation . subarray ( trimmedTypeName , 0 , nameEnd ) ; } TypeReference typeReference ; if ( CharOperation . indexOf ( '.' , trimmedTypeName ) == - 1 ) { typeReference = new SingleTypeReference ( trimmedTypeName , position ) ; } else { typeReference = new QualifiedTypeReference ( CharOperation . splitOn ( '.' , trimmedTypeName ) , positions ) ; } int dimCount = CharOperation . occurencesOf ( '[' , this . evaluationContext . localVariableTypeNames [ i ] ) ; if ( dimCount > 0 ) { typeReference = copyDims ( typeReference , dimCount ) ; } NameReference init = new SingleNameReference ( CharOperation . concat ( LOCAL_VAR_PREFIX , this . evaluationContext . localVariableNames [ i ] ) , position ) ; LocalDeclaration declaration = new LocalDeclaration ( this . evaluationContext . localVariableNames [ i ] , start , end ) ; declaration . initialization = init ; declaration . type = typeReference ; declaration . modifiers = this . evaluationContext . localVariableModifiers [ i ] ; newStatements [ i ] = declaration ; } TryStatement tryStatement = new TryStatement ( ) ; Block tryBlock = new Block ( methodDecl . explicitDeclarations ) ; tryBlock . sourceStart = start ; tryBlock . sourceEnd = end ; tryBlock . statements = methodDecl . statements ; tryStatement . tryBlock = tryBlock ; Block finallyBlock = new Block ( 0 ) ; finallyBlock . sourceStart = start ; finallyBlock . sourceEnd = end ; finallyBlock . statements = new Statement [ varCount ] ; for ( int i = 0 ; i < varCount ; i ++ ) { SingleNameReference nameRef = new SingleNameReference ( this . evaluationContext . localVariableNames [ i ] , position ) ; finallyBlock . statements [ i ] = new Assignment ( new SingleNameReference ( CharOperation . concat ( LOCAL_VAR_PREFIX , this . evaluationContext . localVariableNames [ i ] ) , position ) , nameRef , nameRef . sourceEnd ) ; } tryStatement . finallyBlock = finallyBlock ; newStatements [ varCount ] = tryStatement ; methodDecl . statements = newStatements ; } } protected void consumeMethodInvocationName ( ) { if ( this . scanner . startPosition >= this . codeSnippetStart && this . scanner . startPosition <= this . codeSnippetEnd + 1 + this . lineSeparatorLength && isTopLevelType ( ) ) { MessageSend m = newMessageSend ( ) ; m . sourceEnd = this . rParenPos ; m . sourceStart = ( int ) ( ( m . nameSourcePosition = this . identifierPositionStack [ this . identifierPtr ] ) >>> 32 ) ; m . selector = this . identifierStack [ this . identifierPtr -- ] ; if ( this . identifierLengthStack [ this . identifierLengthPtr ] == 1 ) { m . receiver = new CodeSnippetThisReference ( 0 , 0 , this . evaluationContext , true ) ; this . identifierLengthPtr -- ; } else { this . identifierLengthStack [ this . identifierLengthPtr ] -- ; m . receiver = getUnspecifiedReference ( ) ; m . sourceStart = m . receiver . sourceStart ; } pushOnExpressionStack ( m ) ; } else { super . consumeMethodInvocationName ( ) ; } } protected void consumeMethodInvocationNameWithTypeArguments ( ) { if ( this . scanner . startPosition >= this . codeSnippetStart && this . scanner . startPosition <= this . codeSnippetEnd + 1 + this . lineSeparatorLength && isTopLevelType ( ) ) { MessageSend m = newMessageSendWithTypeArguments ( ) ; m . sourceEnd = this . rParenPos ; m . sourceStart = ( int ) ( ( m . nameSourcePosition = this . identifierPositionStack [ this . identifierPtr ] ) >>> 32 ) ; m . selector = this . identifierStack [ this . identifierPtr -- ] ; this . identifierLengthPtr -- ; int length = this . genericsLengthStack [ this . genericsLengthPtr -- ] ; this . genericsPtr -= length ; System . arraycopy ( this . genericsStack , this . genericsPtr + 1 , m . typeArguments = new TypeReference [ length ] , 0 , length ) ; this . intPtr -- ; m . receiver = getUnspecifiedReference ( ) ; m . sourceStart = m . receiver . sourceStart ; pushOnExpressionStack ( m ) ; } else { super . consumeMethodInvocationNameWithTypeArguments ( ) ; } } protected void consumeMethodInvocationSuper ( ) { MessageSend m = newMessageSend ( ) ; m . sourceStart = this . intStack [ this . intPtr -- ] ; m . sourceEnd = this . rParenPos ; m . nameSourcePosition = this . identifierPositionStack [ this . identifierPtr ] ; m . selector = this . identifierStack [ this . identifierPtr -- ] ; this . identifierLengthPtr -- ; m . receiver = new CodeSnippetSuperReference ( m . sourceStart , this . endPosition ) ; pushOnExpressionStack ( m ) ; } protected void consumeMethodInvocationSuperWithTypeArguments ( ) { MessageSend m = newMessageSendWithTypeArguments ( ) ; this . intPtr -- ; m . sourceEnd = this . rParenPos ; m . nameSourcePosition = this . identifierPositionStack [ this . identifierPtr ] ; m . selector = this . identifierStack [ this . identifierPtr -- ] ; this . identifierLengthPtr -- ; int length = this . genericsLengthStack [ this . genericsLengthPtr -- ] ; this . genericsPtr -= length ; System . arraycopy ( this . genericsStack , this . genericsPtr + 1 , m . typeArguments = new TypeReference [ length ] , 0 , length ) ; m . sourceStart = this . intStack [ this . intPtr -- ] ; m . receiver = new CodeSnippetSuperReference ( m . sourceStart , this . endPosition ) ; pushOnExpressionStack ( m ) ; } protected void consumePrimaryNoNewArrayThis ( ) { if ( this . scanner . startPosition >= this . codeSnippetStart && this . scanner . startPosition <= this . codeSnippetEnd + 1 + this . lineSeparatorLength && isTopLevelType ( ) ) { pushOnExpressionStack ( new CodeSnippetThisReference ( this . intStack [ this . intPtr -- ] , this . endPosition , this . evaluationContext , false ) ) ; } else { super . consumePrimaryNoNewArrayThis ( ) ; } } protected void consumeStatementBreak ( ) { super . consumeStatementBreak ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementBreakWithLabel ( ) { super . consumeStatementBreakWithLabel ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementCatch ( ) { super . consumeStatementCatch ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementContinue ( ) { super . consumeStatementContinue ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementContinueWithLabel ( ) { super . consumeStatementContinueWithLabel ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementDo ( ) { super . consumeStatementDo ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementFor ( ) { super . consumeStatementFor ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementIfNoElse ( ) { super . consumeStatementIfNoElse ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementIfWithElse ( ) { super . consumeStatementIfWithElse ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementLabel ( ) { super . consumeStatementLabel ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementReturn ( ) { if ( ( this . hasRecoveredOnExpression || ( this . scanner . startPosition >= this . codeSnippetStart && this . scanner . startPosition <= this . codeSnippetEnd + 1 + this . lineSeparatorLength ) ) && this . expressionLengthStack [ this . expressionLengthPtr ] != 0 && isTopLevelType ( ) ) { this . expressionLengthPtr -- ; Expression expression = this . expressionStack [ this . expressionPtr -- ] ; pushOnAstStack ( new CodeSnippetReturnStatement ( expression , expression . sourceStart , expression . sourceEnd ) ) ; } else { super . consumeStatementReturn ( ) ; } recordLastStatementIfNeeded ( ) ; } protected void consumeStatementSwitch ( ) { super . consumeStatementSwitch ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementSynchronized ( ) { super . consumeStatementSynchronized ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementThrow ( ) { super . consumeStatementThrow ( ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementTry ( boolean arg_0 , boolean arg_1 ) { super . consumeStatementTry ( arg_0 , arg_1 ) ; recordLastStatementIfNeeded ( ) ; } protected void consumeStatementWhile ( ) { super . consumeStatementWhile ( ) ; recordLastStatementIfNeeded ( ) ; } protected CompilationUnitDeclaration endParse ( int act ) { if ( this . hasRecoveredOnExpression ) { CompilationResult unitResult = this . compilationUnit . compilationResult ; if ( act != ERROR_ACTION ) { for ( int i = 0 ; i < unitResult . problemCount ; i ++ ) { unitResult . problems [ i ] = null ; } unitResult . problemCount = 0 ; if ( this . referenceContext instanceof AbstractMethodDeclaration ) { ( ( AbstractMethodDeclaration ) this . referenceContext ) . ignoreFurtherInvestigation = false ; } if ( this . referenceContext instanceof CompilationUnitDeclaration ) { ( ( CompilationUnitDeclaration ) this . referenceContext ) . ignoreFurtherInvestigation = false ; } consumeStatementReturn ( ) ; int fieldsCount = ( this . evaluationContext . localVariableNames == null ? 0 : this . evaluationContext . localVariableNames . length ) + ( this . evaluationContext . declaringTypeName == null ? 0 : 1 ) ; if ( this . astPtr > ( this . diet ? 0 : 2 + fieldsCount ) ) { consumeBlockStatements ( ) ; } consumeMethodBody ( ) ; if ( ! this . diet ) { consumeMethodDeclaration ( true ) ; if ( fieldsCount > 0 ) { consumeClassBodyDeclarations ( ) ; } consumeClassBodyDeclarationsopt ( ) ; consumeClassDeclaration ( ) ; consumeInternalCompilationUnitWithTypes ( ) ; consumeCompilationUnit ( ) ; } this . lastAct = ACCEPT_ACTION ; } else { int maxRegularPos = 0 , problemCount = unitResult . problemCount ; for ( int i = 0 ; i < this . problemCountBeforeRecovery ; i ++ ) { if ( unitResult . problems [ i ] . getID ( ) == IProblem . UnmatchedBracket ) continue ; int start = unitResult . problems [ i ] . getSourceStart ( ) ; if ( start > maxRegularPos && start <= this . codeSnippetEnd ) { maxRegularPos = start ; } } int maxRecoveryPos = 0 ; for ( int i = this . problemCountBeforeRecovery ; i < problemCount ; i ++ ) { if ( unitResult . problems [ i ] . getID ( ) == IProblem . UnmatchedBracket ) continue ; int start = unitResult . problems [ i ] . getSourceStart ( ) ; if ( start > maxRecoveryPos && start <= this . codeSnippetEnd ) { maxRecoveryPos = start ; } } if ( maxRecoveryPos > maxRegularPos ) { System . arraycopy ( unitResult . problems , this . problemCountBeforeRecovery , unitResult . problems , 0 , problemCount - this . problemCountBeforeRecovery ) ; unitResult . problemCount -= this . problemCountBeforeRecovery ; } else { unitResult . problemCount -= ( problemCount - this . problemCountBeforeRecovery ) ; } for ( int i = unitResult . problemCount ; i < problemCount ; i ++ ) { unitResult . problems [ i ] = null ; } } } return super . endParse ( act ) ; } protected NameReference getUnspecifiedReference ( ) { if ( this . scanner . startPosition >= this . codeSnippetStart && this . scanner . startPosition <= this . codeSnippetEnd + 1 + this . lineSeparatorLength ) { int length ; NameReference ref ; if ( ( length = this . identifierLengthStack [ this . identifierLengthPtr -- ] ) == 1 ) { ref = new CodeSnippetSingleNameReference ( this . identifierStack [ this . identifierPtr ] , this . identifierPositionStack [ this . identifierPtr -- ] , this . evaluationContext ) ; } else { char [ ] [ ] tokens = new char [ length ] [ ] ; this . identifierPtr -= length ; System . arraycopy ( this . identifierStack , this . identifierPtr + 1 , tokens , 0 , length ) ; long [ ] positions = new long [ length ] ; System . arraycopy ( this . identifierPositionStack , this . identifierPtr + 1 , positions , 0 , length ) ; ref = new CodeSnippetQualifiedNameReference ( tokens , positions , ( int ) ( this . identifierPositionStack [ this . identifierPtr + 1 ] >> 32 ) , ( int ) this . identifierPositionStack [ this . identifierPtr + length ] , this . evaluationContext ) ; } return ref ; } else { return super . getUnspecifiedReference ( ) ; } } protected NameReference getUnspecifiedReferenceOptimized ( ) { if ( this . scanner . startPosition >= this . codeSnippetStart && this . scanner . startPosition <= this . codeSnippetEnd + 1 + this . lineSeparatorLength ) { int length ; NameReference ref ; if ( ( length = this . identifierLengthStack [ this . identifierLengthPtr -- ] ) == 1 ) { ref = new CodeSnippetSingleNameReference ( this . identifierStack [ this . identifierPtr ] , this . identifierPositionStack [ this . identifierPtr -- ] , this . evaluationContext ) ; ref . bits &= ~ ASTNode . RestrictiveFlagMASK ; ref . bits |= Binding . LOCAL | Binding . FIELD ; return ref ; } char [ ] [ ] tokens = new char [ length ] [ ] ; this . identifierPtr -= length ; System . arraycopy ( this . identifierStack , this . identifierPtr + 1 , tokens , 0 , length ) ; long [ ] positions = new long [ length ] ; System . arraycopy ( this . identifierPositionStack , this . identifierPtr + 1 , positions , 0 , length ) ; ref = new CodeSnippetQualifiedNameReference ( tokens , positions , ( int ) ( this . identifierPositionStack [ this . identifierPtr + 1 ] >> 32 ) , ( int ) this . identifierPositionStack [ this . identifierPtr + length ] , this . evaluationContext ) ; ref . bits &= ~ ASTNode . RestrictiveFlagMASK ; ref . bits |= Binding . LOCAL | Binding . FIELD ; return ref ; } else { return super . getUnspecifiedReferenceOptimized ( ) ; } } protected void ignoreExpressionAssignment ( ) { super . ignoreExpressionAssignment ( ) ; recordLastStatementIfNeeded ( ) ; } private boolean isTopLevelType ( ) { return this . nestedType == ( this . diet ? 0 : 1 ) ; } protected MessageSend newMessageSend ( ) { CodeSnippetMessageSend m = new CodeSnippetMessageSend ( this . evaluationContext ) ; int length ; if ( ( length = this . expressionLengthStack [ this . expressionLengthPtr -- ] ) != 0 ) { this . expressionPtr -= length ; System . arraycopy ( this . expressionStack , this . expressionPtr + 1 , m . arguments = new Expression [ length ] , 0 , length ) ; } return m ; } protected MessageSend newMessageSendWithTypeArguments ( ) { CodeSnippetMessageSend m = new CodeSnippetMessageSend ( this . evaluationContext ) ; int length ; if ( ( length = this . expressionLengthStack [ this . expressionLengthPtr -- ] ) != 0 ) { this . expressionPtr -= length ; System . arraycopy ( this . expressionStack , this . expressionPtr + 1 , m . arguments = new Expression [ length ] , 0 , length ) ; } return m ; } private void recordLastStatementIfNeeded ( ) { if ( ( isTopLevelType ( ) ) && ( this . scanner . startPosition <= this . codeSnippetEnd + this . lineSeparatorLength ) ) { this . lastStatement = this . scanner . startPosition ; } } protected void reportSyntaxErrors ( boolean isDietParse , int oldFirstToken ) { if ( ! isDietParse ) { this . scanner . initialPosition = this . lastStatement ; this . scanner . eofPosition = this . codeSnippetEnd + 1 ; oldFirstToken = TokenNameTWIDDLE ; } super . reportSyntaxErrors ( isDietParse , oldFirstToken ) ; } protected boolean resumeOnSyntaxError ( ) { if ( this . diet || this . hasRecoveredOnExpression ) { return false ; } this . problemCountBeforeRecovery = this . compilationUnit . compilationResult . problemCount ; if ( this . lastStatement < 0 ) { this . lastStatement = this . codeSnippetStart ; } this . scanner . initialPosition = this . lastStatement ; this . scanner . startPosition = this . lastStatement ; this . scanner . currentPosition = this . lastStatement ; this . scanner . eofPosition = this . codeSnippetEnd < Integer . MAX_VALUE ? this . codeSnippetEnd + 1 : this . codeSnippetEnd ; this . scanner . commentPtr = - 1 ; this . expressionPtr = - 1 ; this . identifierPtr = - 1 ; this . identifierLengthPtr = - 1 ; goForExpression ( ) ; this . hasRecoveredOnExpression = true ; this . hasReportedError = false ; this . hasError = false ; return true ; } } </s>