protected void finishedWith( String sourceLocator, CompilationResult result, char[] mainTypeName, ArrayList definedTypeNames, ArrayList duplicateTypeNames) { char[][] previousTypeNames = this.newState.getDefinedTypeNamesFor(sourceLocator); if (previousTypeNames == null) previousTypeNames = new char[][] {mainTypeName}; IPath packagePath = null; next: for (int i = 0, l = previousTypeNames.length; i < l; i++) { char[] previous = previousTypeNames[i]; for (int j = 0, m = definedTypeNames.size(); j < m; j++) if (CharOperation.equals(previous, (char[]) definedTypeNames.get(j))) continue next; SourceFile sourceFile = (SourceFile) result.getCompilationUnit(); if (packagePath == null) { int count = sourceFile.sourceLocation.sourceFolder.getFullPath().segmentCount(); packagePath = sourceFile.resource.getFullPath().removeFirstSegments(count).removeLastSegments(1); } if (this.secondaryTypesToRemove == null) this.secondaryTypesToRemove = new SimpleLookupTable(); ArrayList types = (ArrayList) this.secondaryTypesToRemove.get(sourceFile.sourceLocation.binaryFolder); if (types == null) types = new ArrayList(definedTypeNames.size()); types.add(packagePath.append(new String(previous))); this.secondaryTypesToRemove.put(sourceFile.sourceLocation.binaryFolder, types); } super.finishedWith(sourceLocator, result, mainTypeName, definedTypeNames, duplicateTypeNames); }
public void resolveReceiver() { if (this.receiver == null) return; if (this.receiver.modifiers != 0) { this.scope .problemReporter() .illegalModifiers( this.receiver.declarationSourceStart, this.receiver.declarationSourceEnd); } TypeBinding resolvedReceiverType = this.receiver.type.resolvedType; if (this.binding == null || resolvedReceiverType == null || !resolvedReceiverType.isValidBinding()) { return; } ReferenceBinding declaringClass = this.binding.declaringClass; /* neither static methods nor methods in anonymous types can have explicit 'this' */ if (this.isStatic() || declaringClass.isAnonymousType()) { this.scope.problemReporter().disallowedThisParameter(this.receiver); return; // No need to do further validation } ReferenceBinding enclosingReceiver = this.scope.enclosingReceiverType(); if (this.isConstructor()) { /* Only non static member types or local types can declare explicit 'this' params in constructors */ if (declaringClass.isStatic() || (declaringClass.tagBits & (TagBits.IsLocalType | TagBits.IsMemberType)) == 0) { /* neither member nor local type */ this.scope.problemReporter().disallowedThisParameter(this.receiver); return; // No need to do further validation } enclosingReceiver = enclosingReceiver.enclosingType(); } char[][] tokens = (this.receiver.qualifyingName == null) ? null : this.receiver.qualifyingName.getName(); if (this.isConstructor()) { if (tokens == null || tokens.length > 1 || !CharOperation.equals(enclosingReceiver.sourceName(), tokens[0])) { this.scope .problemReporter() .illegalQualifierForExplicitThis(this.receiver, enclosingReceiver); this.receiver.qualifyingName = null; } } else if (tokens != null && tokens.length > 0) { this.scope.problemReporter().illegalQualifierForExplicitThis2(this.receiver); this.receiver.qualifyingName = null; } if (TypeBinding.notEquals(enclosingReceiver, resolvedReceiverType)) { this.scope.problemReporter().illegalTypeForExplicitThis(this.receiver, enclosingReceiver); } if (this.receiver.type.hasNullTypeAnnotation(AnnotationPosition.ANY)) { this.scope.problemReporter().nullAnnotationUnsupportedLocation(this.receiver.type); } }
/** Record the thrown exception type bindings in the corresponding type references. */ public void bindThrownExceptions() { if (this.thrownExceptions != null && this.binding != null && this.binding.thrownExceptions != null) { int thrownExceptionLength = this.thrownExceptions.length; int length = this.binding.thrownExceptions.length; if (length == thrownExceptionLength) { for (int i = 0; i < length; i++) { this.thrownExceptions[i].resolvedType = this.binding.thrownExceptions[i]; } } else { int bindingIndex = 0; for (int i = 0; i < thrownExceptionLength && bindingIndex < length; i++) { TypeReference thrownException = this.thrownExceptions[i]; ReferenceBinding thrownExceptionBinding = this.binding.thrownExceptions[bindingIndex]; char[][] bindingCompoundName = thrownExceptionBinding.compoundName; if (bindingCompoundName == null) continue; // skip problem case if (thrownException instanceof SingleTypeReference) { // single type reference int lengthName = bindingCompoundName.length; char[] thrownExceptionTypeName = thrownException.getTypeName()[0]; if (CharOperation.equals( thrownExceptionTypeName, bindingCompoundName[lengthName - 1])) { thrownException.resolvedType = thrownExceptionBinding; bindingIndex++; } } else { // qualified type reference if (CharOperation.equals(thrownException.getTypeName(), bindingCompoundName)) { thrownException.resolvedType = thrownExceptionBinding; bindingIndex++; } } } } } }
protected void addDependentsOf( IPath path, boolean isStructuralChange, StringSet qualifiedNames, StringSet simpleNames, StringSet rootNames) { path = path.setDevice(null); if (isStructuralChange) { String last = path.lastSegment(); if (last.length() == TypeConstants.PACKAGE_INFO_NAME.length) if (CharOperation.equals(last.toCharArray(), TypeConstants.PACKAGE_INFO_NAME)) { path = path.removeLastSegments( 1); // the package-info file has changed so blame the package itself /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=323785, in the case of default package, there is no need to blame the package itself as there can be no annotations or documentation comment tags in the package-info file that can influence the rest of the package. Just bail out so we don't touch null objects below. */ if (path.isEmpty()) return; } } if (isStructuralChange && !this.hasStructuralChanges) { this.newState.tagAsStructurallyChanged(); this.hasStructuralChanges = true; } // the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are just 'X' rootNames.add(path.segment(0)); String packageName = path.removeLastSegments(1).toString(); boolean wasNew = qualifiedNames.add(packageName); String typeName = path.lastSegment(); int memberIndex = typeName.indexOf('$'); if (memberIndex > 0) typeName = typeName.substring(0, memberIndex); wasNew = simpleNames.add(typeName) | wasNew; if (wasNew && JavaBuilder.DEBUG) System.out.println( " will look for dependents of " //$NON-NLS-1$ + typeName + " in " + packageName); //$NON-NLS-1$ }
/** * @see * org.eclipse.jdt.internal.core.builder.AbstractImageBuilder#writeClassFileContents(org.eclipse.jdt.internal.compiler.ClassFile, * org.eclipse.core.resources.IFile, java.lang.String, boolean, * org.eclipse.jdt.internal.core.builder.SourceFile) */ protected void writeClassFileContents( ClassFile classfile, IFile file, String qualifiedFileName, boolean isTopLevelType, SourceFile compilationUnit) throws CoreException { // Before writing out the class file, compare it to the previous file // If structural changes occurred then add dependent source files byte[] bytes = classfile.getBytes(); if (file.exists()) { if (writeClassFileCheck(file, qualifiedFileName, bytes) || compilationUnit.updateClassFile) { // see 46093 if (JavaBuilder.DEBUG) System.out.println("Writing changed class file " + file.getName()); // $NON-NLS-1$ if (!file.isDerived()) file.setDerived(true, null); file.setContents(new ByteArrayInputStream(bytes), true, false, null); } else if (JavaBuilder.DEBUG) { System.out.println("Skipped over unchanged class file " + file.getName()); // $NON-NLS-1$ } } else { if (isTopLevelType) addDependentsOf(new Path(qualifiedFileName), true); // new type if (JavaBuilder.DEBUG) System.out.println("Writing new class file " + file.getName()); // $NON-NLS-1$ try { file.create(new ByteArrayInputStream(bytes), IResource.FORCE | IResource.DERIVED, null); } catch (CoreException e) { if (e.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) { IStatus status = e.getStatus(); if (status instanceof IResourceStatus) { IPath oldFilePath = ((IResourceStatus) status).getPath(); char[] oldTypeName = oldFilePath.removeFileExtension().lastSegment().toCharArray(); char[][] previousTypeNames = this.newState.getDefinedTypeNamesFor(compilationUnit.typeLocator()); boolean fromSameFile = false; if (previousTypeNames == null) { fromSameFile = CharOperation.equals(compilationUnit.getMainTypeName(), oldTypeName); } else { for (int i = 0, l = previousTypeNames.length; i < l; i++) { if (CharOperation.equals(previousTypeNames[i], oldTypeName)) { fromSameFile = true; break; } } } if (fromSameFile) { // file is defined by the same compilationUnit, but won't be deleted until later so do // it now IFile collision = file.getParent().getFile(new Path(oldFilePath.lastSegment())); collision.delete(true, false, null); boolean success = false; try { file.create( new ByteArrayInputStream(bytes), IResource.FORCE | IResource.DERIVED, null); success = true; } catch (CoreException ignored) { // ignore the second exception } if (success) return; } } // catch the case that a type has been renamed and collides on disk with an // as-yet-to-be-deleted type throw new AbortCompilation(true, new AbortIncrementalBuildException(qualifiedFileName)); } throw e; // rethrow } } }