/** * Compute the tagbits for standard annotations. For source types, these could require lazily * resolving corresponding annotation nodes, in case of forward references. * * @see org.eclipse.jdt.internal.compiler.lookup.Binding#getAnnotationTagBits() */ public long getAnnotationTagBits() { FieldBinding originalField = original(); if ((originalField.tagBits & TagBits.AnnotationResolved) == 0 && originalField.declaringClass instanceof SourceTypeBinding) { ClassScope scope = ((SourceTypeBinding) originalField.declaringClass).scope; if (scope == null) { // synthetic fields do not have a scope nor any annotations this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved); return 0; } TypeDeclaration typeDecl = scope.referenceContext; FieldDeclaration fieldDecl = typeDecl.declarationOf(originalField); if (fieldDecl != null) { MethodScope initializationScope = isStatic() ? typeDecl.staticInitializerScope : typeDecl.initializerScope; FieldBinding previousField = initializationScope.initializedField; int previousFieldID = initializationScope.lastVisibleFieldID; try { initializationScope.initializedField = originalField; initializationScope.lastVisibleFieldID = originalField.id; ASTNode.resolveAnnotations(initializationScope, fieldDecl.annotations, originalField); } finally { initializationScope.initializedField = previousField; initializationScope.lastVisibleFieldID = previousFieldID; } } } return originalField.tagBits; }
public Constant constant() { Constant fieldConstant = this.constant; if (fieldConstant == null) { if (isFinal()) { // The field has not been yet type checked. // It also means that the field is not coming from a class that // has already been compiled. It can only be from a class within // compilation units to process. Thus the field is NOT from a BinaryTypeBinbing FieldBinding originalField = original(); if (originalField.declaringClass instanceof SourceTypeBinding) { SourceTypeBinding sourceType = (SourceTypeBinding) originalField.declaringClass; if (sourceType.scope != null) { TypeDeclaration typeDecl = sourceType.scope.referenceContext; FieldDeclaration fieldDecl = typeDecl.declarationOf(originalField); MethodScope initScope = originalField.isStatic() ? typeDecl.staticInitializerScope : typeDecl.initializerScope; boolean old = initScope.insideTypeAnnotation; try { initScope.insideTypeAnnotation = false; fieldDecl.resolve(initScope); // side effect on binding } finally { initScope.insideTypeAnnotation = old; } fieldConstant = originalField.constant == null ? Constant.NotAConstant : originalField.constant; } else { fieldConstant = Constant.NotAConstant; // shouldn't occur per construction (paranoid null check) } } else { fieldConstant = Constant.NotAConstant; // shouldn't occur per construction (paranoid null check) } } else { fieldConstant = Constant.NotAConstant; } this.constant = fieldConstant; } return fieldConstant; }
// version for invocation from LambdaExpression: static void createArgumentBindings( Argument[] arguments, MethodBinding binding, MethodScope scope) { boolean useTypeAnnotations = scope.environment().usesNullTypeAnnotations(); if (arguments != null && binding != null) { for (int i = 0, length = arguments.length; i < length; i++) { Argument argument = arguments[i]; binding.parameters[i] = argument.createBinding(scope, binding.parameters[i]); if (useTypeAnnotations) continue; // no business with SE7 null annotations in the 1.8 case. // createBinding() has resolved annotations, now transfer nullness info from the argument to // the method: long argTypeTagBits = (argument.binding.tagBits & TagBits.AnnotationNullMASK); if (argTypeTagBits != 0) { if (binding.parameterNonNullness == null) { binding.parameterNonNullness = new Boolean[arguments.length]; binding.tagBits |= TagBits.IsNullnessKnown; } binding.parameterNonNullness[i] = Boolean.valueOf(argTypeTagBits == TagBits.AnnotationNonNull); } } } }
public void resolve(BlockScope upperScope) { // special scope for secret locals optimization. this.scope = new BlockScope(upperScope); BlockScope tryScope = new BlockScope(scope); BlockScope finallyScope = null; if (finallyBlock != null) { if (finallyBlock.isEmptyBlock()) { if ((finallyBlock.bits & UndocumentedEmptyBlockMASK) != 0) { scope .problemReporter() .undocumentedEmptyBlock(finallyBlock.sourceStart, finallyBlock.sourceEnd); } } else { finallyScope = new BlockScope(scope, false); // don't add it yet to parent scope // provision for returning and forcing the finally block to run MethodScope methodScope = scope.methodScope(); // the type does not matter as long as it is not a base type if (!upperScope.compilerOptions().inlineJsrBytecode) { this.returnAddressVariable = new LocalVariableBinding( SecretReturnName, upperScope.getJavaLangObject(), AccDefault, false); finallyScope.addLocalVariable(returnAddressVariable); this.returnAddressVariable.setConstant(NotAConstant); // not inlinable } this.subRoutineStartLabel = new Label(); this.anyExceptionVariable = new LocalVariableBinding( SecretAnyHandlerName, scope.getJavaLangThrowable(), AccDefault, false); finallyScope.addLocalVariable(this.anyExceptionVariable); this.anyExceptionVariable.setConstant(NotAConstant); // not inlinable if (!methodScope.isInsideInitializer()) { MethodBinding methodBinding = ((AbstractMethodDeclaration) methodScope.referenceContext).binding; if (methodBinding != null) { TypeBinding methodReturnType = methodBinding.returnType; if (methodReturnType.id != T_void) { this.secretReturnValue = new LocalVariableBinding( SecretLocalDeclarationName, methodReturnType, AccDefault, false); finallyScope.addLocalVariable(this.secretReturnValue); this.secretReturnValue.setConstant(NotAConstant); // not inlinable } } } finallyBlock.resolveUsing(finallyScope); // force the finally scope to have variable positions shifted after its try scope and catch // ones finallyScope.shiftScopes = new BlockScope[catchArguments == null ? 1 : catchArguments.length + 1]; finallyScope.shiftScopes[0] = tryScope; } } this.tryBlock.resolveUsing(tryScope); // arguments type are checked against JavaLangThrowable in resolveForCatch(..) if (this.catchBlocks != null) { int length = this.catchArguments.length; TypeBinding[] argumentTypes = new TypeBinding[length]; boolean catchHasError = false; for (int i = 0; i < length; i++) { BlockScope catchScope = new BlockScope(scope); if (finallyScope != null) { finallyScope.shiftScopes[i + 1] = catchScope; } // side effect on catchScope in resolveForCatch(..) if ((argumentTypes[i] = catchArguments[i].resolveForCatch(catchScope)) == null) { catchHasError = true; } catchBlocks[i].resolveUsing(catchScope); } if (catchHasError) { return; } // Verify that the catch clause are ordered in the right way: // more specialized first. this.caughtExceptionTypes = new ReferenceBinding[length]; for (int i = 0; i < length; i++) { caughtExceptionTypes[i] = (ReferenceBinding) argumentTypes[i]; for (int j = 0; j < i; j++) { if (caughtExceptionTypes[i].isCompatibleWith(argumentTypes[j])) { scope .problemReporter() .wrongSequenceOfExceptionTypesError( this, caughtExceptionTypes[i], i, argumentTypes[j]); } } } } else { caughtExceptionTypes = new ReferenceBinding[0]; } if (finallyScope != null) { // add finallyScope as last subscope, so it can be shifted behind try/catch subscopes. // the shifting is necessary to achieve no overlay in between the finally scope and its // sibling in term of local variable positions. this.scope.addSubscope(finallyScope); } }