/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Michael Spector <spektom@gmail.com> - Bug 243886 *******************************************************************************/ package org.eclipse.wst.jsdt.internal.compiler.problem; import java.io.CharConversionException; import java.io.PrintWriter; import java.io.StringWriter; import java.text.MessageFormat; import org.eclipse.wst.jsdt.core.compiler.CategorizedProblem; import org.eclipse.wst.jsdt.core.compiler.CharOperation; import org.eclipse.wst.jsdt.core.compiler.IProblem; import org.eclipse.wst.jsdt.core.compiler.InvalidInputException; import org.eclipse.wst.jsdt.core.infer.InferredAttribute; import org.eclipse.wst.jsdt.core.infer.InferredType; import org.eclipse.wst.jsdt.internal.compiler.CompilationResult; import org.eclipse.wst.jsdt.internal.compiler.IErrorHandlingPolicy; import org.eclipse.wst.jsdt.internal.compiler.IProblemFactory; import org.eclipse.wst.jsdt.internal.compiler.ast.ASTNode; import org.eclipse.wst.jsdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.wst.jsdt.internal.compiler.ast.AbstractVariableDeclaration; import org.eclipse.wst.jsdt.internal.compiler.ast.AllocationExpression; import org.eclipse.wst.jsdt.internal.compiler.ast.Argument; import org.eclipse.wst.jsdt.internal.compiler.ast.ArrayQualifiedTypeReference; import org.eclipse.wst.jsdt.internal.compiler.ast.ArrayTypeReference; import org.eclipse.wst.jsdt.internal.compiler.ast.Assignment; import org.eclipse.wst.jsdt.internal.compiler.ast.BinaryExpression; import org.eclipse.wst.jsdt.internal.compiler.ast.Block; import org.eclipse.wst.jsdt.internal.compiler.ast.BranchStatement; import org.eclipse.wst.jsdt.internal.compiler.ast.CaseStatement; import org.eclipse.wst.jsdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.wst.jsdt.internal.compiler.ast.CompoundAssignment; import org.eclipse.wst.jsdt.internal.compiler.ast.ConstructorDeclaration; import org.eclipse.wst.jsdt.internal.compiler.ast.ExplicitConstructorCall; import org.eclipse.wst.jsdt.internal.compiler.ast.Expression; import org.eclipse.wst.jsdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.wst.jsdt.internal.compiler.ast.FieldReference; import org.eclipse.wst.jsdt.internal.compiler.ast.ImportReference; import org.eclipse.wst.jsdt.internal.compiler.ast.InstanceOfExpression; import org.eclipse.wst.jsdt.internal.compiler.ast.IntLiteral; import org.eclipse.wst.jsdt.internal.compiler.ast.LabeledStatement; import org.eclipse.wst.jsdt.internal.compiler.ast.Literal; import org.eclipse.wst.jsdt.internal.compiler.ast.LocalDeclaration; import org.eclipse.wst.jsdt.internal.compiler.ast.MessageSend; import org.eclipse.wst.jsdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.wst.jsdt.internal.compiler.ast.NameReference; import org.eclipse.wst.jsdt.internal.compiler.ast.NumberLiteral; import org.eclipse.wst.jsdt.internal.compiler.ast.QualifiedNameReference; import org.eclipse.wst.jsdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.wst.jsdt.internal.compiler.ast.Reference; import org.eclipse.wst.jsdt.internal.compiler.ast.SingleNameReference; import org.eclipse.wst.jsdt.internal.compiler.ast.Statement; import org.eclipse.wst.jsdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.wst.jsdt.internal.compiler.ast.TypeReference; import org.eclipse.wst.jsdt.internal.compiler.ast.UnaryExpression; import org.eclipse.wst.jsdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.wst.jsdt.internal.compiler.env.ICompilationUnit; import org.eclipse.wst.jsdt.internal.compiler.impl.CompilerOptions; import org.eclipse.wst.jsdt.internal.compiler.impl.ReferenceContext; import org.eclipse.wst.jsdt.internal.compiler.lookup.ArrayBinding; import org.eclipse.wst.jsdt.internal.compiler.lookup.Binding; import org.eclipse.wst.jsdt.internal.compiler.lookup.ExtraCompilerModifiers; import org.eclipse.wst.jsdt.internal.compiler.lookup.FieldBinding; import org.eclipse.wst.jsdt.internal.compiler.lookup.LocalVariableBinding; import org.eclipse.wst.jsdt.internal.compiler.lookup.MethodBinding; import org.eclipse.wst.jsdt.internal.compiler.lookup.ProblemMethodBinding; import org.eclipse.wst.jsdt.internal.compiler.lookup.ProblemReasons; import org.eclipse.wst.jsdt.internal.compiler.lookup.ReferenceBinding; import org.eclipse.wst.jsdt.internal.compiler.lookup.Scope; import org.eclipse.wst.jsdt.internal.compiler.lookup.SourceTypeBinding; import org.eclipse.wst.jsdt.internal.compiler.lookup.TypeBinding; import org.eclipse.wst.jsdt.internal.compiler.lookup.TypeConstants; import org.eclipse.wst.jsdt.internal.compiler.lookup.TypeIds; import org.eclipse.wst.jsdt.internal.compiler.parser.Parser; import org.eclipse.wst.jsdt.internal.compiler.parser.RecoveryScanner; import org.eclipse.wst.jsdt.internal.compiler.parser.Scanner; import org.eclipse.wst.jsdt.internal.compiler.parser.ScannerHelper; import org.eclipse.wst.jsdt.internal.compiler.parser.TerminalTokens; import org.eclipse.wst.jsdt.internal.compiler.util.Messages; import org.eclipse.wst.jsdt.internal.compiler.util.Util; public class ProblemReporter extends ProblemHandler { public ReferenceContext referenceContext; private Scanner positionScanner; public static long getIrritant(int problemID) { switch(problemID){ case IProblem.UninitializedLocalVariable: return CompilerOptions.UninitializedLocalVariable; case IProblem.UninitializedGlobalVariable: return CompilerOptions.UninitializedGlobalVariable; case IProblem.MaskedCatch : return CompilerOptions.MaskedCatchBlock; case IProblem.MethodButWithConstructorName : return CompilerOptions.MethodWithConstructorName; /* START -------------------------------- Bug 203292 Type/Method/Filed resolution error configuration --------------------- */ case IProblem.UndefinedName: return CompilerOptions.UnresolvedType; case IProblem.UndefinedFunction: case IProblem.UndefinedMethod: case IProblem.UndefinedConstructor: return CompilerOptions.UnresolvedMethod; /* END -------------------------------- Bug 203292 Type/Method/Filed resolution error configuration --------------------- */ case IProblem.OptionalSemiColon: return CompilerOptions.OptionalSemicolon; case IProblem.LooseVarDecl: return CompilerOptions.LooseVariableDecl; /* START -------------------------------- Bug 197884 Loosly defined var (for statement) and optional semi-colon --------------------- */ /* END -------------------------------- Bug 197884 Loosly defined var (for statement) and optional semi-colon --------------------- */ case IProblem.OverridingDeprecatedMethod : case IProblem.UsingDeprecatedType : case IProblem.UsingDeprecatedMethod : case IProblem.UsingDeprecatedConstructor : case IProblem.UsingDeprecatedField : return CompilerOptions.UsingDeprecatedAPI; case IProblem.LocalVariableIsNeverUsed : return CompilerOptions.UnusedLocalVariable; case IProblem.ArgumentIsNeverUsed : return CompilerOptions.UnusedArgument; case IProblem.NeedToEmulateFieldReadAccess : case IProblem.NeedToEmulateFieldWriteAccess : case IProblem.NeedToEmulateMethodAccess : case IProblem.NeedToEmulateConstructorAccess : return CompilerOptions.AccessEmulation; case IProblem.NonExternalizedStringLiteral : case IProblem.UnnecessaryNLSTag : return CompilerOptions.NonExternalizedString; case IProblem.UseAssertAsAnIdentifier : return CompilerOptions.AssertUsedAsAnIdentifier; case IProblem.UseEnumAsAnIdentifier : return CompilerOptions.EnumUsedAsAnIdentifier; case IProblem.NonStaticAccessToStaticMethod : case IProblem.NonStaticAccessToStaticField : return CompilerOptions.NonStaticAccessToStatic; case IProblem.IndirectAccessToStaticMethod : case IProblem.IndirectAccessToStaticField : case IProblem.IndirectAccessToStaticType : return CompilerOptions.IndirectStaticAccess; case IProblem.AssignmentHasNoEffect: return CompilerOptions.NoEffectAssignment; case IProblem.UnusedPrivateConstructor: case IProblem.UnusedPrivateMethod: case IProblem.UnusedPrivateField: case IProblem.UnusedPrivateType: return CompilerOptions.UnusedPrivateMember; case IProblem.LocalVariableHidingLocalVariable: case IProblem.LocalVariableHidingField: case IProblem.ArgumentHidingLocalVariable: case IProblem.ArgumentHidingField: return CompilerOptions.LocalVariableHiding; case IProblem.FieldHidingLocalVariable: case IProblem.FieldHidingField: return CompilerOptions.FieldHiding; case IProblem.TypeHidingType: return CompilerOptions.TypeHiding; case IProblem.PossibleAccidentalBooleanAssignment: return CompilerOptions.AccidentalBooleanAssign; case IProblem.SuperfluousSemicolon: case IProblem.EmptyControlFlowStatement: return CompilerOptions.EmptyStatement; case IProblem.UndocumentedEmptyBlock: return CompilerOptions.UndocumentedEmptyBlock; case IProblem.UnnecessaryInstanceof: return CompilerOptions.UnnecessaryTypeCheck; case IProblem.FinallyMustCompleteNormally: return CompilerOptions.FinallyBlockNotCompleting; case IProblem.UnusedMethodDeclaredThrownException: case IProblem.UnusedConstructorDeclaredThrownException: return CompilerOptions.UnusedDeclaredThrownException; case IProblem.UnqualifiedFieldAccess: return CompilerOptions.UnqualifiedFieldAccess; case IProblem.UnnecessaryElse: return CompilerOptions.UnnecessaryElse; case IProblem.ForbiddenReference: return CompilerOptions.ForbiddenReference; case IProblem.DiscouragedReference: return CompilerOptions.DiscouragedReference; case IProblem.NullLocalVariableReference: return CompilerOptions.NullReference; case IProblem.PotentialNullLocalVariableReference: return CompilerOptions.PotentialNullReference; case IProblem.RedefinedLocal: return CompilerOptions.DuplicateLocalVariables; case IProblem.RedundantLocalVariableNullAssignment: case IProblem.RedundantNullCheckOnNonNullLocalVariable: case IProblem.RedundantNullCheckOnNullLocalVariable: case IProblem.NonNullLocalVariableComparisonYieldsFalse: case IProblem.NullLocalVariableComparisonYieldsFalse: case IProblem.NullLocalVariableInstanceofYieldsFalse: return CompilerOptions.RedundantNullCheck; case IProblem.UnusedLabel : return CompilerOptions.UnusedLabel; case IProblem.JavadocUnexpectedTag: case IProblem.JavadocDuplicateReturnTag: case IProblem.JavadocInvalidThrowsClass: case IProblem.JavadocInvalidSeeReference: case IProblem.JavadocInvalidParamTagName: case IProblem.JavadocMalformedSeeReference: case IProblem.JavadocInvalidSeeHref: case IProblem.JavadocInvalidSeeArgs: case IProblem.JavadocInvalidTag: case IProblem.JavadocUnterminatedInlineTag: case IProblem.JavadocMissingHashCharacter: case IProblem.JavadocEmptyReturnTag: case IProblem.JavadocUnexpectedText: case IProblem.JavadocInvalidParamName: case IProblem.JavadocDuplicateParamName: case IProblem.JavadocMissingParamName: case IProblem.JavadocMissingIdentifier: case IProblem.JavadocInvalidMemberTypeQualification: case IProblem.JavadocInvalidThrowsClassName: case IProblem.JavadocDuplicateThrowsClassName: case IProblem.JavadocMissingThrowsClassName: case IProblem.JavadocMissingSeeReference: case IProblem.JavadocUndefinedField: case IProblem.JavadocAmbiguousField: case IProblem.JavadocUndefinedConstructor: case IProblem.JavadocAmbiguousConstructor: case IProblem.JavadocUndefinedMethod: case IProblem.JavadocAmbiguousMethod: case IProblem.JavadocParameterMismatch: case IProblem.JavadocUndefinedType: case IProblem.JavadocAmbiguousType: case IProblem.JavadocInternalTypeNameProvided: case IProblem.JavadocNoMessageSendOnArrayType: case IProblem.JavadocNoMessageSendOnBaseType: case IProblem.JavadocInheritedMethodHidesEnclosingName: case IProblem.JavadocInheritedFieldHidesEnclosingName: case IProblem.JavadocInheritedNameHidesEnclosingTypeName: case IProblem.JavadocNonStaticTypeFromStaticInvocation: case IProblem.JavadocNotVisibleField: case IProblem.JavadocNotVisibleConstructor: case IProblem.JavadocNotVisibleMethod: case IProblem.JavadocNotVisibleType: case IProblem.JavadocUsingDeprecatedField: case IProblem.JavadocUsingDeprecatedConstructor: case IProblem.JavadocUsingDeprecatedMethod: case IProblem.JavadocUsingDeprecatedType: case IProblem.JavadocHiddenReference: return CompilerOptions.InvalidJavadoc; case IProblem.JavadocMissingParamTag: case IProblem.JavadocMissingReturnTag: case IProblem.JavadocMissingThrowsTag: return CompilerOptions.MissingJavadocTags; case IProblem.JavadocMissing: return CompilerOptions.MissingJavadocComments; case IProblem.ParameterAssignment: return CompilerOptions.ParameterAssignment; case IProblem.FallthroughCase: return CompilerOptions.FallthroughCase; case IProblem.OverridingMethodWithoutSuperInvocation: return CompilerOptions.OverridingMethodWithoutSuperInvocation; case IProblem.UndefinedField: return CompilerOptions.UndefinedField; case IProblem.WrongNumberOfArguments: return CompilerOptions.WrongNumberOfArguments; case IProblem.MissingSemiColon: return CompilerOptions.OptionalSemicolon; } return 0; } /** * Compute problem category ID based on problem ID * @param problemID * @return a category ID * @see CategorizedProblem */ public static int getProblemCategory(int severity, int problemID) { categorizeOnIrritant: { // fatal problems even if optional are all falling into same category (not irritant based) if ((severity & ProblemSeverities.Fatal) != 0) break categorizeOnIrritant; long irritant = getIrritant(problemID); int irritantInt = (int) irritant; if (irritantInt == irritant) { switch (irritantInt) { case (int)CompilerOptions.MethodWithConstructorName: case (int)CompilerOptions.AccessEmulation: case (int)CompilerOptions.AssertUsedAsAnIdentifier: case (int)CompilerOptions.NonStaticAccessToStatic: case (int)CompilerOptions.UnqualifiedFieldAccess: case (int)CompilerOptions.UndocumentedEmptyBlock: case (int)CompilerOptions.IndirectStaticAccess: return CategorizedProblem.CAT_CODE_STYLE; case (int)CompilerOptions.MaskedCatchBlock: case (int)CompilerOptions.NoEffectAssignment: case (int)CompilerOptions.AccidentalBooleanAssign: case (int)CompilerOptions.EmptyStatement: case (int)CompilerOptions.FinallyBlockNotCompleting: case (int)CompilerOptions.UndefinedField: return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM; case (int)CompilerOptions.LocalVariableHiding: case (int)CompilerOptions.FieldHiding: return CategorizedProblem.CAT_NAME_SHADOWING_CONFLICT; case (int)CompilerOptions.UnusedLocalVariable: case (int)CompilerOptions.UnusedArgument: case (int)CompilerOptions.UnusedPrivateMember: case (int)CompilerOptions.UnusedDeclaredThrownException: case (int)CompilerOptions.UnnecessaryTypeCheck: case (int)CompilerOptions.UnnecessaryElse: return CategorizedProblem.CAT_UNNECESSARY_CODE; case (int)CompilerOptions.Task: return CategorizedProblem.CAT_UNSPECIFIED; // TODO may want to improve case (int)CompilerOptions.MissingJavadocComments: case (int)CompilerOptions.MissingJavadocTags: case (int)CompilerOptions.InvalidJavadoc: case (int)(CompilerOptions.InvalidJavadoc | CompilerOptions.UsingDeprecatedAPI): return CategorizedProblem.CAT_JAVADOC; default: break categorizeOnIrritant; } } else { irritantInt = (int)(irritant >>> 32); switch (irritantInt) { case (int)(CompilerOptions.FinalParameterBound >>> 32): case (int)(CompilerOptions.EnumUsedAsAnIdentifier >>> 32): case (int)(CompilerOptions.ParameterAssignment >>> 32): return CategorizedProblem.CAT_CODE_STYLE; case (int)(CompilerOptions.NullReference >>> 32): case (int)(CompilerOptions.PotentialNullReference >>> 32): case (int)(CompilerOptions.DuplicateLocalVariables >>> 32): case (int)(CompilerOptions.RedundantNullCheck >>> 32): case (int)(CompilerOptions.FallthroughCase >>> 32): case (int)(CompilerOptions.OverridingMethodWithoutSuperInvocation >>> 32): case (int)(CompilerOptions.UninitializedLocalVariable >>> 32): case (int)(CompilerOptions.UninitializedGlobalVariable >>> 32): return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM; case (int)(CompilerOptions.TypeHiding >>> 32): return CategorizedProblem.CAT_NAME_SHADOWING_CONFLICT; case (int)(CompilerOptions.UnusedLabel >>> 32): return CategorizedProblem.CAT_UNNECESSARY_CODE; case (int)(CompilerOptions.ForbiddenReference >>> 32): case (int)(CompilerOptions.DiscouragedReference >>> 32): return CategorizedProblem.CAT_RESTRICTION; default: break categorizeOnIrritant; } } } // categorize fatal problems per ID switch (problemID) { case IProblem.IsClassPathCorrect : case IProblem.CorruptedSignature : return CategorizedProblem.CAT_BUILDPATH; default : if ((problemID & IProblem.Syntax) != 0) return CategorizedProblem.CAT_SYNTAX; if ((problemID & IProblem.ImportRelated) != 0) return CategorizedProblem.CAT_IMPORT; if ((problemID & IProblem.TypeRelated) != 0) return CategorizedProblem.CAT_TYPE; if ((problemID & (IProblem.FieldRelated|IProblem.MethodRelated|IProblem.ConstructorRelated)) != 0) return CategorizedProblem.CAT_MEMBER; } return CategorizedProblem.CAT_INTERNAL; } public ProblemReporter(IErrorHandlingPolicy policy, CompilerOptions options, IProblemFactory problemFactory) { super(policy, options, problemFactory); } public void abortDueToInternalError(String errorMessage) { this.abortDueToInternalError(errorMessage, null); } public void abortDueToInternalError(String errorMessage, ASTNode location) { String[] arguments = new String[] {errorMessage}; this.handle( IProblem.Unclassified, arguments, arguments, ProblemSeverities.Error | ProblemSeverities.Abort | ProblemSeverities.Fatal, location == null ? 0 : location.sourceStart, location == null ? 0 : location.sourceEnd); } public void alreadyDefinedLabel(char[] labelName, ASTNode location) { String[] arguments = new String[] {new String(labelName)}; this.handle( IProblem.DuplicateLabel, arguments, arguments, location.sourceStart, location.sourceEnd); } public void assignmentHasNoEffect(AbstractVariableDeclaration location, char[] name){ int severity = computeSeverity(IProblem.AssignmentHasNoEffect); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] { new String(name) }; int start = location.sourceStart; int end = location.sourceEnd; if (location.initialization != null) { end = location.initialization.sourceEnd; } this.handle( IProblem.AssignmentHasNoEffect, arguments, arguments, severity, start, end); } public void assignmentHasNoEffect(Assignment location, char[] name){ int severity = computeSeverity(IProblem.AssignmentHasNoEffect); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] { new String(name) }; this.handle( IProblem.AssignmentHasNoEffect, arguments, arguments, severity, location.sourceStart, location.sourceEnd); } public void cannotReadSource(CompilationUnitDeclaration unit, AbortCompilationUnit abortException, boolean verbose) { String fileName = new String(unit.compilationResult.fileName); if (abortException.exception instanceof CharConversionException) { // specific encoding issue String encoding = abortException.encoding; if (encoding == null) { encoding = System.getProperty("file.encoding"); //$NON-NLS-1$ } String[] arguments = new String[]{ fileName, encoding, }; this.handle( IProblem.InvalidEncoding, arguments, arguments, 0, 0); return; } StringWriter stringWriter = new StringWriter(); PrintWriter writer = new PrintWriter(stringWriter); if (verbose) { abortException.exception.printStackTrace(writer); } else { writer.print(abortException.exception.getClass().getName()); writer.print(':'); writer.print(abortException.exception.getMessage()); } String exceptionTrace = stringWriter.toString(); String[] arguments = new String[]{ fileName, exceptionTrace, }; this.handle( IProblem.CannotReadSource, arguments, arguments, 0, 0); } public void cannotReturnOutsideFunction(ASTNode location) { this.handle( IProblem.CannotReturnOutsideFunction, NoArgument, NoArgument, location.sourceStart, location.sourceEnd); } /* * Given the current configuration, answers which category the problem * falls into: * ProblemSeverities.Error | ProblemSeverities.Warning | ProblemSeverities.Ignore * when different from Ignore, severity can be coupled with ProblemSeverities.Optional * to indicate that this problem is configurable through options */ public int computeSeverity(int problemID){ /* * If semantic validation is not enabled and this is anything but a * syntax, documentation, or task problem, ignore. */ if (!this.options.enableSemanticValidation && (problemID & IProblem.Syntax) == 0 && (problemID & IProblem.Javadoc) == 0 && problemID != IProblem.Task) { return ProblemSeverities.Ignore; } switch (problemID) { case IProblem.Task : return ProblemSeverities.Warning; case IProblem.TypeCollidesWithPackage : return ProblemSeverities.Warning; /* * JS Type mismatch is set to default as Warning */ case IProblem.NotAFunction: case IProblem.TypeMismatch: return ProblemSeverities.Warning; // case IProblem.UndefinedName: // case IProblem.UndefinedFunction: // case IProblem.UndefinedMethod: // case IProblem.UndefinedField: // case IProblem.UndefinedConstructor: // break; /* * Javadoc tags resolved references errors */ case IProblem.JavadocInvalidParamName: case IProblem.JavadocDuplicateParamName: case IProblem.JavadocMissingParamName: case IProblem.JavadocMissingIdentifier: case IProblem.JavadocInvalidMemberTypeQualification: case IProblem.JavadocInvalidThrowsClassName: case IProblem.JavadocDuplicateThrowsClassName: case IProblem.JavadocMissingThrowsClassName: case IProblem.JavadocMissingSeeReference: case IProblem.JavadocUndefinedField: case IProblem.JavadocAmbiguousField: case IProblem.JavadocUndefinedConstructor: case IProblem.JavadocAmbiguousConstructor: case IProblem.JavadocUndefinedMethod: case IProblem.JavadocAmbiguousMethod: case IProblem.JavadocParameterMismatch: case IProblem.JavadocUndefinedType: case IProblem.JavadocAmbiguousType: case IProblem.JavadocInternalTypeNameProvided: case IProblem.JavadocNoMessageSendOnArrayType: case IProblem.JavadocNoMessageSendOnBaseType: case IProblem.JavadocInheritedMethodHidesEnclosingName: case IProblem.JavadocInheritedFieldHidesEnclosingName: case IProblem.JavadocInheritedNameHidesEnclosingTypeName: case IProblem.JavadocNonStaticTypeFromStaticInvocation: case IProblem.JavadocEmptyReturnTag: if (!this.options.reportInvalidJavadocTags) { return ProblemSeverities.Ignore; } break; /* * Javadoc invalid tags due to deprecated references */ case IProblem.JavadocUsingDeprecatedField: case IProblem.JavadocUsingDeprecatedConstructor: case IProblem.JavadocUsingDeprecatedMethod: case IProblem.JavadocUsingDeprecatedType: if (!(this.options.reportInvalidJavadocTags && this.options.reportInvalidJavadocTagsDeprecatedRef)) { return ProblemSeverities.Ignore; } break; /* * Javadoc invalid tags due to non-visible references */ case IProblem.JavadocNotVisibleField: case IProblem.JavadocNotVisibleConstructor: case IProblem.JavadocNotVisibleMethod: case IProblem.JavadocNotVisibleType: case IProblem.JavadocHiddenReference: if (!(this.options.reportInvalidJavadocTags && this.options.reportInvalidJavadocTagsNotVisibleRef)) { return ProblemSeverities.Ignore; } break; } long irritant = getIrritant(problemID); if (irritant != 0) { if ((problemID & IProblem.Javadoc) != 0 && !this.options.docCommentSupport) return ProblemSeverities.Ignore; return this.options.getSeverity(irritant); } return ProblemSeverities.Error | ProblemSeverities.Fatal; } public void constantOutOfFormat(NumberLiteral literal) { // the literal is not in a correct format // this code is called on IntLiteral // example 000811 ...the 8 is uncorrect. if (literal instanceof IntLiteral) { char[] source = literal.source(); try { final String Radix; final int radix; if ((source[1] == 'x') || (source[1] == 'X')) { radix = 16; Radix = "Hex"; //$NON-NLS-1$ } else { radix = 8; Radix = "Octal"; //$NON-NLS-1$ } //look for the first digit that is incorrect int place = -1; label : for (int i = radix == 8 ? 1 : 2; i < source.length; i++) { if (ScannerHelper.digit(source[i], radix) == -1) { place = i; break label; } } String[] arguments = new String[] { new String(literal.literalType(null).readableName()), // numeric literals do not need scope to reach type Radix + " " + new String(source) + " (digit " + new String(new char[] {source[place]}) + ")"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ this.handle( IProblem.NumericValueOutOfRange, arguments, arguments, ProblemSeverities.Ignore, literal.sourceStart, literal.sourceEnd); return; } catch (IndexOutOfBoundsException ex) { // should never happen } // just in case .... use a predefined error.. // we should never come here...(except if the code changes !) this.constantOutOfRange(literal, literal.literalType(null)); // numeric literals do not need scope to reach type } } public void constantOutOfRange(Literal literal, TypeBinding literalType) { String[] arguments = new String[] {new String(literalType.readableName()), new String(literal.source())}; this.handle( IProblem.NumericValueOutOfRange, arguments, arguments, ProblemSeverities.Ignore, literal.sourceStart, literal.sourceEnd); } public void corruptedSignature(TypeBinding enclosingType, char[] signature, int position) { this.handle( IProblem.CorruptedSignature, new String[] { new String(enclosingType.readableName()), new String(signature), String.valueOf(position) }, new String[] { new String(enclosingType.shortReadableName()), new String(signature), String.valueOf(position) }, ProblemSeverities.Ignore, 0, 0); } public void deprecatedField(FieldBinding field, ASTNode location) { int severity = computeSeverity(IProblem.UsingDeprecatedField); if (severity == ProblemSeverities.Ignore) return; this.handle( IProblem.UsingDeprecatedField, new String[] {new String(field.declaringClass.readableName()), new String(field.name)}, new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)}, ProblemSeverities.Ignore, nodeSourceStart(field, location), nodeSourceEnd(field, location)); } public void deprecatedMethod(MethodBinding method, ASTNode location) { boolean isConstructor = method.isConstructor(); int severity = computeSeverity(isConstructor ? IProblem.UsingDeprecatedConstructor : IProblem.UsingDeprecatedMethod); if (severity == ProblemSeverities.Ignore) return; if (isConstructor) { this.handle( IProblem.UsingDeprecatedConstructor, new String[] {new String(method.declaringClass.readableName()), typesAsString(method.isVarargs(), method.parameters, false)}, new String[] {new String(method.declaringClass.shortReadableName()), typesAsString(method.isVarargs(), method.parameters, true)}, ProblemSeverities.Ignore, location.sourceStart, location.sourceEnd); } else { this.handle( IProblem.UsingDeprecatedMethod, new String[] {new String(method.declaringClass.readableName()), new String(method.selector), typesAsString(method.isVarargs(), method.parameters, false)}, new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), typesAsString(method.isVarargs(), method.parameters, true)}, ProblemSeverities.Ignore, location.sourceStart, location.sourceEnd); } } public void deprecatedType(TypeBinding type, ASTNode location) { if (location == null) return; // 1G828DN - no type ref for synthetic arguments int severity = computeSeverity(IProblem.UsingDeprecatedType); if (severity == ProblemSeverities.Ignore) return; type = type.leafComponentType(); this.handle( IProblem.UsingDeprecatedType, new String[] {new String(type.readableName())}, new String[] {new String(type.shortReadableName())}, ProblemSeverities.Ignore, location.sourceStart, nodeSourceEnd(null, location)); } public void duplicateCase(CaseStatement caseStatement) { this.handle( IProblem.DuplicateCase, NoArgument, NoArgument, caseStatement.sourceStart, caseStatement.sourceEnd); } public void duplicateDefaultCase(ASTNode statement) { this.handle( IProblem.DuplicateDefaultCase, NoArgument, NoArgument, statement.sourceStart, statement.sourceEnd); } public void duplicateFieldInType(SourceTypeBinding type, FieldDeclaration fieldDecl) { this.handle( IProblem.DuplicateField, new String[] {new String(type.sourceName()), new String(fieldDecl.name)}, new String[] {new String(type.shortReadableName()), new String(fieldDecl.name)}, ProblemSeverities.Ignore, fieldDecl.sourceStart, fieldDecl.sourceEnd); } public void duplicateFieldInType(SourceTypeBinding type, InferredAttribute fieldDecl) { this.handle( IProblem.DuplicateField, new String[] {new String(type.sourceName()), new String(fieldDecl.name)}, new String[] {new String(type.shortReadableName()), new String(fieldDecl.name)}, ProblemSeverities.Ignore, fieldDecl.sourceStart, fieldDecl.sourceEnd); } public void duplicateMethodInType( Binding type, AbstractMethodDeclaration methodDecl) { MethodBinding method = methodDecl.binding; this.handle( IProblem.DuplicateMethod, new String[] { new String(methodDecl.getSafeName()), new String(method.declaringClass.readableName()), typesAsString(method.isVarargs(), method.parameters, false)}, new String[] { new String(methodDecl.getSafeName()), new String(method.declaringClass.shortReadableName()), typesAsString(method.isVarargs(), method.parameters, true)}, ProblemSeverities.Ignore, methodDecl.sourceStart, methodDecl.sourceEnd); } public void duplicateTypes(CompilationUnitDeclaration compUnitDecl, InferredType typeDecl) { String[] arguments = new String[] {new String(compUnitDecl.getFileName()), new String(typeDecl.getName())}; this.referenceContext = compUnitDecl; // report the problem against the type not the entire compilation unit this.handle( IProblem.DuplicateTypes, arguments, arguments, ProblemSeverities.Ignore, typeDecl.sourceStart, typeDecl.sourceEnd, this.referenceContext, compUnitDecl.compilationResult); } public void emptyControlFlowStatement(int sourceStart, int sourceEnd) { this.handle( IProblem.EmptyControlFlowStatement, NoArgument, NoArgument, sourceStart, sourceEnd); } public void expressionShouldBeAVariable(Expression expression) { this.handle( IProblem.ExpressionShouldBeAVariable, NoArgument, NoArgument, expression.sourceStart, expression.sourceEnd); } public void fieldHiding(FieldDeclaration fieldDecl, Binding hiddenVariable) { FieldBinding field = fieldDecl.binding; boolean isLocal = hiddenVariable instanceof LocalVariableBinding; int severity = computeSeverity(isLocal ? IProblem.FieldHidingLocalVariable : IProblem.FieldHidingField); if (severity == ProblemSeverities.Ignore) return; if (isLocal) { this.handle( IProblem.FieldHidingLocalVariable, new String[] {new String(field.declaringClass.readableName()), new String(field.name) }, new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name) }, ProblemSeverities.Ignore, nodeSourceStart(hiddenVariable, fieldDecl), nodeSourceEnd(hiddenVariable, fieldDecl)); } else if (hiddenVariable instanceof FieldBinding) { FieldBinding hiddenField = (FieldBinding) hiddenVariable; this.handle( IProblem.FieldHidingField, new String[] {new String(field.declaringClass.readableName()), new String(field.name) , new String(hiddenField.declaringClass.readableName()) }, new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name) , new String(hiddenField.declaringClass.shortReadableName()) }, ProblemSeverities.Ignore, nodeSourceStart(hiddenField, fieldDecl), nodeSourceEnd(hiddenField, fieldDecl)); } } public void finallyMustCompleteNormally(Block finallyBlock) { this.handle( IProblem.FinallyMustCompleteNormally, NoArgument, NoArgument, finallyBlock.sourceStart, finallyBlock.sourceEnd); } public void forbiddenReference(FieldBinding field, ASTNode location, String messageTemplate, int problemId) { this.handle( problemId, new String[] { new String(field.readableName()) }, // distinct from msg arg for quickfix purpose new String[] { MessageFormat.format(messageTemplate, new String[]{ new String(field.shortReadableName()), new String(field.declaringClass.shortReadableName())})}, ProblemSeverities.Ignore, nodeSourceStart(field, location), nodeSourceEnd(field, location)); } public void forbiddenReference(MethodBinding method, ASTNode location, String messageTemplate, int problemId) { if (method.isConstructor()) this.handle( problemId, new String[] { new String(method.readableName()) }, // distinct from msg arg for quickfix purpose new String[] { MessageFormat.format(messageTemplate, new String[]{new String(method.shortReadableName())})}, ProblemSeverities.Ignore, location.sourceStart, location.sourceEnd); else this.handle( problemId, new String[] { new String(method.readableName()) }, // distinct from msg arg for quickfix purpose new String[] { MessageFormat.format(messageTemplate, new String[]{ new String(method.shortReadableName()), new String(method.declaringClass.shortReadableName())})}, ProblemSeverities.Ignore, location.sourceStart, location.sourceEnd); } public void forbiddenReference(TypeBinding type, ASTNode location, String messageTemplate, int problemId) { if (location == null) return; int severity = computeSeverity(problemId); if (severity == ProblemSeverities.Ignore) return; // this problem has a message template extracted from the access restriction rule this.handle( problemId, new String[] { new String(type.readableName()) }, // distinct from msg arg for quickfix purpose new String[] { MessageFormat.format(messageTemplate, new String[]{ new String(type.shortReadableName())})}, ProblemSeverities.Ignore, location.sourceStart, location.sourceEnd); } public void forwardReference(Reference reference, int indexInQualification, TypeBinding type) { this.handle( IProblem.ReferenceToForwardField, NoArgument, NoArgument, ProblemSeverities.Ignore, reference.sourceStart, reference.sourceEnd); } // use this private API when the compilation unit result can be found through the // reference context. Otherwise, use the other API taking a problem and a compilation result // as arguments private void handle( int problemId, String[] problemArguments, String[] messageArguments, int problemStartPosition, int problemEndPosition){ this.handle( problemId, problemArguments, messageArguments, problemStartPosition, problemEndPosition, this.referenceContext, this.referenceContext == null ? null : this.referenceContext.compilationResult()); this.referenceContext = null; } // use this private API when the compilation unit result cannot be found through the // reference context. private void handle( int problemId, String[] problemArguments, String[] messageArguments, int problemStartPosition, int problemEndPosition, CompilationResult unitResult){ this.handle( problemId, problemArguments, messageArguments, problemStartPosition, problemEndPosition, this.referenceContext, unitResult); this.referenceContext = null; } // use this private API when the compilation unit result can be found through the // reference context. Otherwise, use the other API taking a problem and a compilation result // as arguments private void handle( int problemId, String[] problemArguments, String[] messageArguments, int severity, int problemStartPosition, int problemEndPosition){ this.handle( problemId, problemArguments, messageArguments, severity, problemStartPosition, problemEndPosition, this.referenceContext, this.referenceContext == null ? null : this.referenceContext.compilationResult()); this.referenceContext = null; } public void hierarchyCircularity(SourceTypeBinding sourceType, ReferenceBinding superType, TypeReference reference) { int start = 0; int end = 0; if (reference == null) { // can only happen when java.lang.Object is busted start = sourceType.sourceStart(); end = sourceType.sourceEnd(); } else { start = reference.sourceStart; end = reference.sourceEnd; } if (sourceType == superType) this.handle( IProblem.HierarchyCircularitySelfReference, new String[] {new String(sourceType.readableName()) }, new String[] {new String(sourceType.shortReadableName()) }, start, end); else this.handle( IProblem.HierarchyCircularity, new String[] {new String(sourceType.readableName()), new String(superType.readableName())}, new String[] {new String(sourceType.shortReadableName()), new String(superType.shortReadableName())}, start, end); } public void hierarchyHasProblems(SourceTypeBinding type) { String[] arguments = new String[] {new String(type.sourceName())}; this.handle( IProblem.HierarchyHasProblems, arguments, arguments, ProblemSeverities.Ignore, type.sourceStart(), type.sourceEnd()); } public void incompatibleReturnType(MethodBinding currentMethod, MethodBinding inheritedMethod) { StringBuffer methodSignature = new StringBuffer(); methodSignature .append(inheritedMethod.declaringClass.readableName()) .append('.') .append(inheritedMethod.readableName()); StringBuffer shortSignature = new StringBuffer(); shortSignature .append(inheritedMethod.declaringClass.shortReadableName()) .append('.') .append(inheritedMethod.shortReadableName()); int id; final ReferenceBinding declaringClass = currentMethod.declaringClass; id = IProblem.IncompatibleReturnType; AbstractMethodDeclaration method = currentMethod.sourceMethod(); int sourceStart = 0; int sourceEnd = 0; if (method == null) { if (declaringClass instanceof SourceTypeBinding && ((SourceTypeBinding) declaringClass).classScope != null) { SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) declaringClass; sourceStart = sourceTypeBinding.sourceStart(); sourceEnd = sourceTypeBinding.sourceEnd(); } } else if (method.isConstructor() || ((MethodDeclaration) method).returnType==null){ sourceStart = method.sourceStart; sourceEnd = method.sourceEnd; } else { TypeReference returnType = ((MethodDeclaration) method).returnType; sourceStart = returnType.sourceStart; sourceEnd = returnType.sourceEnd; } this.handle( id, new String[] {methodSignature.toString()}, new String[] {shortSignature.toString()}, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void indirectAccessToStaticField(ASTNode location, FieldBinding field){ int severity = computeSeverity(IProblem.IndirectAccessToStaticField); if (severity == ProblemSeverities.Ignore) return; this.handle( IProblem.IndirectAccessToStaticField, new String[] {new String(field.declaringClass.readableName()), new String(field.name)}, new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)}, ProblemSeverities.Ignore, nodeSourceStart(field, location), nodeSourceEnd(field, location)); } public void indirectAccessToStaticMethod(ASTNode location, MethodBinding method) { int severity = computeSeverity(IProblem.IndirectAccessToStaticMethod); if (severity == ProblemSeverities.Ignore) return; this.handle( IProblem.IndirectAccessToStaticMethod, new String[] {new String(method.declaringClass.readableName()), new String(method.selector), typesAsString(method.isVarargs(), method.parameters, false)}, new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), typesAsString(method.isVarargs(), method.parameters, true)}, ProblemSeverities.Ignore, location.sourceStart, location.sourceEnd); } public void inheritedMethodsHaveIncompatibleReturnTypes(SourceTypeBinding type, MethodBinding[] inheritedMethods, int length) { StringBuffer methodSignatures = new StringBuffer(); StringBuffer shortSignatures = new StringBuffer(); for (int i = length; --i >= 0;) { methodSignatures .append(inheritedMethods[i].declaringClass.readableName()) .append('.') .append(inheritedMethods[i].readableName()); shortSignatures .append(inheritedMethods[i].declaringClass.shortReadableName()) .append('.') .append(inheritedMethods[i].shortReadableName()); if (i != 0){ methodSignatures.append(", "); //$NON-NLS-1$ shortSignatures.append(", "); //$NON-NLS-1$ } } this.handle( // Return type is incompatible with %1 // 9.4.2 - The return type from the method is incompatible with the declaration. IProblem.IncompatibleReturnType, new String[] {methodSignatures.toString()}, new String[] {shortSignatures.toString()}, ProblemSeverities.Ignore, type.sourceStart(), type.sourceEnd()); } public void invalidBreak(ASTNode location) { this.handle( IProblem.InvalidBreak, NoArgument, NoArgument, location.sourceStart, location.sourceEnd); } public void invalidConstructor(Statement statement, MethodBinding targetConstructor) { boolean insideDefaultConstructor = (this.referenceContext instanceof ConstructorDeclaration) && ((ConstructorDeclaration)this.referenceContext).isDefaultConstructor(); boolean insideImplicitConstructorCall = (statement instanceof ExplicitConstructorCall) && (((ExplicitConstructorCall) statement).accessMode == ExplicitConstructorCall.ImplicitSuper); int sourceStart = statement.sourceStart; int sourceEnd = statement.sourceEnd; int id = IProblem.UndefinedConstructor; //default... MethodBinding shownConstructor = targetConstructor; switch (targetConstructor.problemId()) { case ProblemReasons.NotFound : if (insideDefaultConstructor){ id = IProblem.UndefinedConstructorInDefaultConstructor; } else if (insideImplicitConstructorCall){ id = IProblem.UndefinedConstructorInImplicitConstructorCall; } else { id = IProblem.UndefinedConstructor; } break; case ProblemReasons.NotVisible : if (insideDefaultConstructor){ id = IProblem.NotVisibleConstructorInDefaultConstructor; } else if (insideImplicitConstructorCall){ id = IProblem.NotVisibleConstructorInImplicitConstructorCall; } else { id = IProblem.NotVisibleConstructor; } ProblemMethodBinding problemConstructor = (ProblemMethodBinding) targetConstructor; if (problemConstructor.closestMatch != null) { shownConstructor = problemConstructor.closestMatch.original(); } break; case ProblemReasons.Ambiguous : if (insideDefaultConstructor){ id = IProblem.AmbiguousConstructorInDefaultConstructor; } else if (insideImplicitConstructorCall){ id = IProblem.AmbiguousConstructorInImplicitConstructorCall; } else { id = IProblem.AmbiguousConstructor; } break; case ProblemReasons.NoError : // 0 default : needImplementation(); // want to fail to see why we were here... break; } this.handle( id, new String[] {new String(targetConstructor.declaringClass.readableName()), typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, false)}, new String[] {new String(targetConstructor.declaringClass.shortReadableName()), typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, true)}, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void invalidContinue(ASTNode location) { this.handle( IProblem.InvalidContinue, NoArgument, NoArgument, location.sourceStart, location.sourceEnd); } public void invalidField(FieldReference fieldRef, TypeBinding searchedType) { if(isRecoveredName(fieldRef.token)) return; int id = IProblem.UndefinedField; FieldBinding field = fieldRef.binding; switch (field.problemId()) { case ProblemReasons.NotFound : id = IProblem.UndefinedField; /* also need to check that the searchedType is the receiver type if (searchedType.isHierarchyInconsistent()) severity = SecondaryError; */ break; case ProblemReasons.NotVisible : this.handle( IProblem.NotVisibleField, new String[] {new String(fieldRef.token), new String(field.declaringClass.readableName())}, new String[] {new String(fieldRef.token), new String(field.declaringClass.shortReadableName())}, ProblemSeverities.Ignore, nodeSourceStart(field, fieldRef), nodeSourceEnd(field, fieldRef)); return; case ProblemReasons.Ambiguous : id = IProblem.AmbiguousField; break; case ProblemReasons.NonStaticReferenceInStaticContext : id = IProblem.NonStaticFieldFromStaticInvocation; break; case ProblemReasons.NonStaticReferenceInConstructorInvocation : id = IProblem.InstanceFieldDuringConstructorInvocation; break; case ProblemReasons.InheritedNameHidesEnclosingName : id = IProblem.InheritedFieldHidesEnclosingName; break; case ProblemReasons.ReceiverTypeNotVisible : this.handle( IProblem.NotVisibleType, // cannot occur in javadoc comments new String[] {new String(searchedType.leafComponentType().readableName())}, new String[] {new String(searchedType.leafComponentType().shortReadableName())}, ProblemSeverities.Ignore, fieldRef.receiver.sourceStart, fieldRef.receiver.sourceEnd); return; case ProblemReasons.NoError : // 0 default : needImplementation(); // want to fail to see why we were here... break; } String[] arguments = new String[] {new String(field.readableName())}; this.handle( id, arguments, arguments, ProblemSeverities.Ignore, nodeSourceStart(field, fieldRef), nodeSourceEnd(field, fieldRef)); } public void invalidField(NameReference nameRef, FieldBinding field) { if (nameRef instanceof QualifiedNameReference) { QualifiedNameReference ref = (QualifiedNameReference) nameRef; if (isRecoveredName(ref.tokens)) return; } else { SingleNameReference ref = (SingleNameReference) nameRef; if (isRecoveredName(ref.token)) return; } int id = IProblem.UndefinedField; switch (field.problemId()) { case ProblemReasons.NotFound : id = IProblem.UndefinedField; break; case ProblemReasons.NotVisible : char[] name = field.readableName(); name = CharOperation.lastSegment(name, '.'); this.handle( IProblem.NotVisibleField, new String[] {new String(name), new String(field.declaringClass.readableName())}, new String[] {new String(name), new String(field.declaringClass.shortReadableName())}, ProblemSeverities.Ignore, nodeSourceStart(field, nameRef), nodeSourceEnd(field, nameRef)); return; case ProblemReasons.Ambiguous : id = IProblem.AmbiguousField; break; case ProblemReasons.NonStaticReferenceInStaticContext : id = IProblem.NonStaticFieldFromStaticInvocation; break; case ProblemReasons.NonStaticReferenceInConstructorInvocation : id = IProblem.InstanceFieldDuringConstructorInvocation; break; case ProblemReasons.InheritedNameHidesEnclosingName : id = IProblem.InheritedFieldHidesEnclosingName; break; case ProblemReasons.ReceiverTypeNotVisible : this.handle( IProblem.NotVisibleType, new String[] {new String(field.declaringClass.leafComponentType().readableName())}, new String[] {new String(field.declaringClass.leafComponentType().shortReadableName())}, ProblemSeverities.Ignore, nameRef.sourceStart, nameRef.sourceEnd); return; case ProblemReasons.NoError : // 0 default : needImplementation(); // want to fail to see why we were here... break; } String[] arguments = new String[] {new String(field.readableName())}; this.handle( id, arguments, arguments, ProblemSeverities.Ignore, nameRef.sourceStart, nameRef.sourceEnd); } public void invalidField(QualifiedNameReference nameRef, FieldBinding field, int index, TypeBinding searchedType) { //the resolution of the index-th field of qname failed //qname.otherBindings[index] is the binding that has produced the error //The different targetted errors should be : //UndefinedField //NotVisibleField //AmbiguousField if (isRecoveredName(nameRef.tokens)) return; if (searchedType.isBaseType()) { this.handle( IProblem.NoFieldOnBaseType, new String[] { new String(searchedType.readableName()), CharOperation.toString(CharOperation.subarray(nameRef.tokens, 0, index)), new String(nameRef.tokens[index])}, new String[] { new String(searchedType.sourceName()), CharOperation.toString(CharOperation.subarray(nameRef.tokens, 0, index)), new String(nameRef.tokens[index])}, ProblemSeverities.Ignore, nameRef.sourceStart, (int) nameRef.sourcePositions[index]); return; } int id = IProblem.UndefinedField; switch (field.problemId()) { case ProblemReasons.NotFound : id = IProblem.UndefinedField; /* also need to check that the searchedType is the receiver type if (searchedType.isHierarchyInconsistent()) severity = SecondaryError; */ break; case ProblemReasons.NotVisible : String fieldName = new String(nameRef.tokens[index]); this.handle( IProblem.NotVisibleField, new String[] {fieldName, new String(field.declaringClass.readableName())}, new String[] {fieldName, new String(field.declaringClass.shortReadableName())}, ProblemSeverities.Ignore, nodeSourceStart(field, nameRef), nodeSourceEnd(field, nameRef)); return; case ProblemReasons.Ambiguous : id = IProblem.AmbiguousField; break; case ProblemReasons.NonStaticReferenceInStaticContext : id = IProblem.NonStaticFieldFromStaticInvocation; break; case ProblemReasons.NonStaticReferenceInConstructorInvocation : id = IProblem.InstanceFieldDuringConstructorInvocation; break; case ProblemReasons.InheritedNameHidesEnclosingName : id = IProblem.InheritedFieldHidesEnclosingName; break; case ProblemReasons.ReceiverTypeNotVisible : this.handle( IProblem.NotVisibleType, new String[] {new String(searchedType.leafComponentType().readableName())}, new String[] {new String(searchedType.leafComponentType().shortReadableName())}, ProblemSeverities.Ignore, nameRef.sourceStart, nameRef.sourceEnd); return; case ProblemReasons.NoError : // 0 default : needImplementation(); // want to fail to see why we were here... break; } String[] arguments = new String[] {CharOperation.toString(CharOperation.subarray(nameRef.tokens, 0, index + 1))}; this.handle( id, arguments, arguments, ProblemSeverities.Ignore, nameRef.sourceStart, (int) nameRef.sourcePositions[index]); } public void invalidMethod(MessageSend messageSend, MethodBinding method) { if (isRecoveredName(messageSend.selector)) return; boolean isFunction = method.declaringClass==null; int id = isFunction? IProblem.UndefinedFunction : IProblem.UndefinedMethod; //default... MethodBinding shownMethod = method; switch (method.problemId()) { case ProblemReasons.NotFound : id = isFunction? IProblem.UndefinedFunction : IProblem.UndefinedMethod; ProblemMethodBinding problemMethod = (ProblemMethodBinding) method; if (problemMethod.closestMatch != null) { shownMethod = problemMethod.closestMatch; String closestParameterTypeNames = typesAsString(shownMethod.isVarargs(), shownMethod.parameters, false); String parameterTypeNames = typesAsString(false, problemMethod.parameters, false); String closestParameterTypeShortNames = typesAsString(shownMethod.isVarargs(), shownMethod.parameters, true); String parameterTypeShortNames = typesAsString(false, problemMethod.parameters, true); this.handle( IProblem.ParameterMismatch, new String[] { new String(shownMethod.declaringClass.readableName()), new String(shownMethod.selector), closestParameterTypeNames, parameterTypeNames }, new String[] { new String(shownMethod.declaringClass.shortReadableName()), new String(shownMethod.selector), closestParameterTypeShortNames, parameterTypeShortNames }, ProblemSeverities.Ignore, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition); return; } break; case ProblemReasons.NotVisible : id = IProblem.NotVisibleMethod; problemMethod = (ProblemMethodBinding) method; if (problemMethod.closestMatch != null) { shownMethod = problemMethod.closestMatch.original(); } break; case ProblemReasons.Ambiguous : id = IProblem.AmbiguousMethod; break; case ProblemReasons.NotAFunction : id = IProblem.NotAFunction; break; case ProblemReasons.InheritedNameHidesEnclosingName : id = IProblem.InheritedMethodHidesEnclosingName; break; case ProblemReasons.NonStaticReferenceInConstructorInvocation : id = IProblem.InstanceMethodDuringConstructorInvocation; break; case ProblemReasons.NonStaticReferenceInStaticContext : id = IProblem.StaticMethodRequested; break; case ProblemReasons.ReceiverTypeNotVisible : this.handle( IProblem.NotVisibleType, // cannot occur in javadoc comments new String[] {new String(method.declaringClass.leafComponentType().readableName())}, new String[] {new String(method.declaringClass.leafComponentType().shortReadableName())}, ProblemSeverities.Ignore, messageSend.receiver.sourceStart, messageSend.receiver.sourceEnd); return; case ProblemReasons.NoError : // 0 default : needImplementation(); // want to fail to see why we were here... break; } String shortName=""; //$NON-NLS-1$ String readableName=""; //$NON-NLS-1$ String methodName=(shownMethod.selector!=null)? new String(shownMethod.selector):""; //$NON-NLS-1$ if (method.declaringClass!=null) { shortName= readableName=new String(method.declaringClass.readableName()); } this.handle( id, new String[] { readableName, shortName, typesAsString(shownMethod.isVarargs(), shownMethod.parameters, false)}, new String[] { shortName, methodName, typesAsString(shownMethod.isVarargs(), shownMethod.parameters, true)}, ProblemSeverities.Ignore, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition); } public void wrongNumberOfArguments(MessageSend functionCall, MethodBinding binding) { String functionName = new String(functionCall.selector); int actualArguments=(functionCall.arguments!=null) ? functionCall.arguments.length : 0; String actualNumber=String.valueOf(actualArguments); String expectingNumber=String.valueOf(binding.parameters.length); this.handle( IProblem.WrongNumberOfArguments, new String[] { functionName,expectingNumber,actualNumber}, //$NON-NLS-1$ new String[] { functionName,expectingNumber,actualNumber}, //$NON-NLS-1$ ProblemSeverities.Ignore, functionCall.sourceStart, functionCall.sourceEnd); } public void wrongNumberOfArguments(AllocationExpression allocationExpression, MethodBinding binding) { char[] typeName = Util.getTypeName(allocationExpression.member); String functionName = typeName!=null ? new String(typeName) : ""; int actualArguments=(allocationExpression.arguments!=null) ? allocationExpression.arguments.length : 0; String actualNumber=String.valueOf(actualArguments); String expectingNumber=String.valueOf(binding.parameters.length); this.handle( IProblem.WrongNumberOfArguments, new String[] { functionName,expectingNumber,actualNumber}, //$NON-NLS-1$ new String[] { functionName,expectingNumber,actualNumber}, //$NON-NLS-1$ ProblemSeverities.Ignore, allocationExpression.sourceStart, allocationExpression.sourceEnd); } public void invalidOperator(BinaryExpression expression, TypeBinding leftType, TypeBinding rightType) { String leftName = new String(leftType.readableName()); String rightName = new String(rightType.readableName()); String leftShortName = new String(leftType.shortReadableName()); String rightShortName = new String(rightType.shortReadableName()); if (leftShortName.equals(rightShortName)){ leftShortName = leftName; rightShortName = rightName; } this.handle( IProblem.InvalidOperator, new String[] { expression.operatorToString(), leftName + ", " + rightName}, //$NON-NLS-1$ new String[] { expression.operatorToString(), leftShortName + ", " + rightShortName}, //$NON-NLS-1$ ProblemSeverities.Ignore, expression.sourceStart, expression.sourceEnd); } public void invalidOperator(CompoundAssignment assign, TypeBinding leftType, TypeBinding rightType) { String leftName = new String(leftType.readableName()); String rightName = new String(rightType.readableName()); String leftShortName = new String(leftType.shortReadableName()); String rightShortName = new String(rightType.shortReadableName()); if (leftShortName.equals(rightShortName)){ leftShortName = leftName; rightShortName = rightName; } this.handle( IProblem.InvalidOperator, new String[] { assign.operatorToString(), leftName + ", " + rightName}, //$NON-NLS-1$ new String[] { assign.operatorToString(), leftShortName + ", " + rightShortName}, //$NON-NLS-1$ ProblemSeverities.Ignore, assign.sourceStart, assign.sourceEnd); } public void invalidOperator(UnaryExpression expression, TypeBinding type) { this.handle( IProblem.InvalidOperator, new String[] {expression.operatorToString(), new String(type.readableName())}, new String[] {expression.operatorToString(), new String(type.shortReadableName())}, ProblemSeverities.Ignore, expression.sourceStart, expression.sourceEnd); } public void invalidType(ASTNode location, TypeBinding type) { if (type instanceof ReferenceBinding) { if (isRecoveredName(((ReferenceBinding)type).compoundName)) return; } else if (type instanceof ArrayBinding) { TypeBinding leafType = ((ArrayBinding)type).leafComponentType; if (leafType instanceof ReferenceBinding) { if (isRecoveredName(((ReferenceBinding)leafType).compoundName)) return; } } int id = IProblem.UndefinedType; // default switch (type.problemId()) { case ProblemReasons.NotFound : id = IProblem.UndefinedType; break; case ProblemReasons.NotVisible : id = IProblem.NotVisibleType; break; case ProblemReasons.Ambiguous : id = IProblem.AmbiguousType; break; case ProblemReasons.InternalNameProvided : id = IProblem.InternalTypeNameProvided; break; case ProblemReasons.InheritedNameHidesEnclosingName : id = IProblem.InheritedTypeHidesEnclosingName; break; case ProblemReasons.NoError : // 0 default : needImplementation(); // want to fail to see why we were here... break; } int end = location.sourceEnd; if (location instanceof QualifiedNameReference) { QualifiedNameReference ref = (QualifiedNameReference) location; if (isRecoveredName(ref.tokens)) return; if (ref.indexOfFirstFieldBinding >= 1) end = (int) ref.sourcePositions[ref.indexOfFirstFieldBinding - 1]; } else if (location instanceof ArrayQualifiedTypeReference) { ArrayQualifiedTypeReference arrayQualifiedTypeReference = (ArrayQualifiedTypeReference) location; if (isRecoveredName(arrayQualifiedTypeReference.tokens)) return; long[] positions = arrayQualifiedTypeReference.sourcePositions; end = (int) positions[positions.length - 1]; } else if (location instanceof QualifiedTypeReference) { QualifiedTypeReference ref = (QualifiedTypeReference) location; if (isRecoveredName(ref.tokens)) return; if (type instanceof ReferenceBinding) { char[][] name = ((ReferenceBinding) type).compoundName; if (name.length <= ref.sourcePositions.length) end = (int) ref.sourcePositions[name.length - 1]; } } else if (location instanceof ImportReference) { ImportReference ref = (ImportReference) location; if (isRecoveredName(ref.tokens)) return; if (type instanceof ReferenceBinding) { char[][] name = ((ReferenceBinding) type).compoundName; end = (int) ref.sourcePositions[name.length - 1]; } } else if (location instanceof ArrayTypeReference) { ArrayTypeReference arrayTypeReference = (ArrayTypeReference) location; if (isRecoveredName(arrayTypeReference.token)) return; end = arrayTypeReference.originalSourceEnd; } this.handle( id, new String[] {new String(type.leafComponentType().readableName()) }, new String[] {new String(type.leafComponentType().shortReadableName())}, ProblemSeverities.Ignore, location.sourceStart, end); } public void invalidUnaryExpression(Expression expression) { this.handle( IProblem.InvalidUnaryExpression, NoArgument, NoArgument, expression.sourceStart, expression.sourceEnd); } public void invalidValueForGetterSetter(Expression expression, boolean isSetter) { int problemID; if (isSetter) { problemID = IProblem.InvalidValueForSetter; } else { problemID = IProblem.InvalidValueForGetter; } this.handle( problemID, NoArgument, NoArgument, expression.sourceStart, expression.sourceEnd); } private boolean isIdentifier(int token) { return token == TerminalTokens.TokenNameIdentifier; } private boolean isKeyword(int token) { switch(token) { case TerminalTokens.TokenNameabstract: case TerminalTokens.TokenNamebyte: case TerminalTokens.TokenNamebreak: case TerminalTokens.TokenNameboolean: case TerminalTokens.TokenNamecase: case TerminalTokens.TokenNamechar: case TerminalTokens.TokenNamecatch: case TerminalTokens.TokenNameclass: case TerminalTokens.TokenNamecontinue: case TerminalTokens.TokenNamedo: case TerminalTokens.TokenNamedouble: case TerminalTokens.TokenNamedefault: case TerminalTokens.TokenNameelse: case TerminalTokens.TokenNameextends: case TerminalTokens.TokenNamefor: case TerminalTokens.TokenNamefinal: case TerminalTokens.TokenNamefloat: case TerminalTokens.TokenNamefalse: case TerminalTokens.TokenNamefinally: case TerminalTokens.TokenNameif: case TerminalTokens.TokenNameint: case TerminalTokens.TokenNameimport: case TerminalTokens.TokenNameinterface: case TerminalTokens.TokenNameimplements: case TerminalTokens.TokenNameinstanceof: case TerminalTokens.TokenNamelong: case TerminalTokens.TokenNamenew: case TerminalTokens.TokenNamenull: case TerminalTokens.TokenNamenative: case TerminalTokens.TokenNamepublic: case TerminalTokens.TokenNamepackage: case TerminalTokens.TokenNameprivate: case TerminalTokens.TokenNameprotected: case TerminalTokens.TokenNamereturn: case TerminalTokens.TokenNameshort: case TerminalTokens.TokenNamesuper: case TerminalTokens.TokenNamestatic: case TerminalTokens.TokenNameswitch: case TerminalTokens.TokenNamesynchronized: case TerminalTokens.TokenNametry: case TerminalTokens.TokenNamethis: case TerminalTokens.TokenNametrue: case TerminalTokens.TokenNamethrow: case TerminalTokens.TokenNamethrows: case TerminalTokens.TokenNametransient: case TerminalTokens.TokenNamevoid: case TerminalTokens.TokenNamevolatile: case TerminalTokens.TokenNamewhile: case TerminalTokens.TokenNamedelete : case TerminalTokens.TokenNamedebugger : case TerminalTokens.TokenNameexport : case TerminalTokens.TokenNamefunction : case TerminalTokens.TokenNamein : // case TerminalTokens.TokenNameinfinity : case TerminalTokens.TokenNameundefined : case TerminalTokens.TokenNamewith : return true; default: return false; } } private boolean isLiteral(int token) { switch(token) { case TerminalTokens.TokenNameIntegerLiteral: case TerminalTokens.TokenNameLongLiteral: case TerminalTokens.TokenNameFloatingPointLiteral: case TerminalTokens.TokenNameDoubleLiteral: case TerminalTokens.TokenNameStringLiteral: case TerminalTokens.TokenNameCharacterLiteral: return true; default: return false; } } private boolean isRecoveredName(char[] simpleName) { return simpleName == RecoveryScanner.FAKE_IDENTIFIER; } private boolean isRecoveredName(char[][] qualifiedName) { if(qualifiedName == null) return false; for (int i = 0; i < qualifiedName.length; i++) { if(qualifiedName[i] == RecoveryScanner.FAKE_IDENTIFIER) return true; } return false; } public void javadocDeprecatedField(FieldBinding field, ASTNode location, int modifiers) { int severity = computeSeverity(IProblem.JavadocUsingDeprecatedField); if (severity == ProblemSeverities.Ignore) return; if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) { this.handle( IProblem.JavadocUsingDeprecatedField, new String[] {new String(field.declaringClass.readableName()), new String(field.name)}, new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)}, ProblemSeverities.Ignore, nodeSourceStart(field, location), nodeSourceEnd(field, location)); } } public void javadocDeprecatedMethod(MethodBinding method, ASTNode location, int modifiers) { boolean isConstructor = method.isConstructor(); int severity = computeSeverity(isConstructor ? IProblem.JavadocUsingDeprecatedConstructor : IProblem.JavadocUsingDeprecatedMethod); if (severity == ProblemSeverities.Ignore) return; if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) { if (isConstructor) { this.handle( IProblem.JavadocUsingDeprecatedConstructor, new String[] {new String(method.declaringClass.readableName()), typesAsString(method.isVarargs(), method.parameters, false)}, new String[] {new String(method.declaringClass.shortReadableName()), typesAsString(method.isVarargs(), method.parameters, true)}, ProblemSeverities.Ignore, location.sourceStart, location.sourceEnd); } else { this.handle( IProblem.JavadocUsingDeprecatedMethod, new String[] {new String(method.declaringClass.readableName()), new String(method.selector), typesAsString(method.isVarargs(), method.parameters, false)}, new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), typesAsString(method.isVarargs(), method.parameters, true)}, ProblemSeverities.Ignore, location.sourceStart, location.sourceEnd); } } } public void javadocDeprecatedType(TypeBinding type, ASTNode location, int modifiers) { if (location == null) return; // 1G828DN - no type ref for synthetic arguments int severity = computeSeverity(IProblem.JavadocUsingDeprecatedType); if (severity == ProblemSeverities.Ignore) return; if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) { if (type.isMemberType() && type instanceof ReferenceBinding && !javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, ((ReferenceBinding)type).modifiers)) { this.handle(IProblem.JavadocHiddenReference, NoArgument, NoArgument, location.sourceStart, location.sourceEnd); } else { this.handle( IProblem.JavadocUsingDeprecatedType, new String[] {new String(type.readableName())}, new String[] {new String(type.shortReadableName())}, ProblemSeverities.Ignore, location.sourceStart, location.sourceEnd); } } } public void javadocDuplicatedParamTag(char[] token, int sourceStart, int sourceEnd, int modifiers) { int severity = computeSeverity(IProblem.JavadocDuplicateParamName); if (severity == ProblemSeverities.Ignore) return; if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) { String[] arguments = new String[] {String.valueOf(token)}; this.handle( IProblem.JavadocDuplicateParamName, arguments, arguments, severity, sourceStart, sourceEnd); } } public void javadocDuplicatedReturnTag(int sourceStart, int sourceEnd){ this.handle(IProblem.JavadocDuplicateReturnTag, NoArgument, NoArgument, sourceStart, sourceEnd); } public void javadocEmptyReturnTag(int sourceStart, int sourceEnd, int modifiers) { int severity = computeSeverity(IProblem.JavadocEmptyReturnTag); if (severity == ProblemSeverities.Ignore) return; if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) { this.handle(IProblem.JavadocEmptyReturnTag, NoArgument, NoArgument, sourceStart, sourceEnd); } } public void javadocHiddenReference(int sourceStart, int sourceEnd, Scope scope, int modifiers) { Scope currentScope = scope; while (currentScope.parent.kind != Scope.COMPILATION_UNIT_SCOPE ) { if (!javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, currentScope.getDeclarationModifiers())) { return; } currentScope = currentScope.parent; } String[] arguments = new String[] { this.options.getVisibilityString(this.options.reportInvalidJavadocTagsVisibility), this.options.getVisibilityString(modifiers) }; this.handle(IProblem.JavadocHiddenReference, arguments, arguments, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void javadocInvalidConstructor(Statement statement, MethodBinding targetConstructor, int modifiers) { if (!javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) return; int id = IProblem.JavadocUndefinedConstructor; //default... switch (targetConstructor.problemId()) { case ProblemReasons.NotFound : id = IProblem.JavadocUndefinedConstructor; break; case ProblemReasons.NotVisible : id = IProblem.JavadocNotVisibleConstructor; break; case ProblemReasons.Ambiguous : id = IProblem.JavadocAmbiguousConstructor; break; case ProblemReasons.NoError : // 0 default : needImplementation(); // want to fail to see why we were here... break; } int severity = computeSeverity(id); if (severity == ProblemSeverities.Ignore) return; this.handle( id, new String[] {new String(targetConstructor.declaringClass.readableName()), typesAsString(targetConstructor.isVarargs(), targetConstructor.parameters, false)}, new String[] {new String(targetConstructor.declaringClass.shortReadableName()), typesAsString(targetConstructor.isVarargs(), targetConstructor.parameters, true)}, ProblemSeverities.Ignore, statement.sourceStart, statement.sourceEnd); } /* * Similar implementation than invalidField(FieldReference...) * Note that following problem id cannot occur for Javadoc: * - NonStaticReferenceInStaticContext : * - NonStaticReferenceInConstructorInvocation : * - ReceiverTypeNotVisible : */ public void javadocInvalidField(int sourceStart, int sourceEnd, Binding fieldBinding, TypeBinding searchedType, int modifiers) { int id = IProblem.JavadocUndefinedField; switch (fieldBinding.problemId()) { case ProblemReasons.NotFound : id = IProblem.JavadocUndefinedField; break; case ProblemReasons.NotVisible : id = IProblem.JavadocNotVisibleField; break; case ProblemReasons.Ambiguous : id = IProblem.JavadocAmbiguousField; break; case ProblemReasons.NoError : // 0 default : needImplementation(); // want to fail to see why we were here... break; } int severity = computeSeverity(id); if (severity == ProblemSeverities.Ignore) return; // report issue if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) { String[] arguments = new String[] {new String(fieldBinding.readableName())}; handle( id, arguments, arguments, ProblemSeverities.Ignore, sourceStart, sourceEnd); } } /* * Similar implementation than invalidMethod(MessageSend...) * Note that following problem id cannot occur for Javadoc: * - NonStaticReferenceInStaticContext : * - NonStaticReferenceInConstructorInvocation : * - ReceiverTypeNotVisible : */ public void javadocInvalidMethod(MessageSend messageSend, MethodBinding method, int modifiers) { if (!javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) return; // set problem id ProblemMethodBinding problemMethod = null; int id = IProblem.JavadocUndefinedMethod; //default... switch (method.problemId()) { case ProblemReasons.NotFound : id = IProblem.JavadocUndefinedMethod; problemMethod = (ProblemMethodBinding) method; if (problemMethod.closestMatch != null) { int severity = computeSeverity(IProblem.JavadocParameterMismatch); if (severity == ProblemSeverities.Ignore) return; String closestParameterTypeNames = typesAsString(problemMethod.closestMatch.isVarargs(), problemMethod.closestMatch.parameters, false); String parameterTypeNames = typesAsString(method.isVarargs(), method.parameters, false); String closestParameterTypeShortNames = typesAsString(problemMethod.closestMatch.isVarargs(), problemMethod.closestMatch.parameters, true); String parameterTypeShortNames = typesAsString(method.isVarargs(), method.parameters, true); if (closestParameterTypeShortNames.equals(parameterTypeShortNames)){ closestParameterTypeShortNames = closestParameterTypeNames; parameterTypeShortNames = parameterTypeNames; } this.handle( IProblem.JavadocParameterMismatch, new String[] { new String(problemMethod.closestMatch.declaringClass.readableName()), new String(problemMethod.closestMatch.selector), closestParameterTypeNames, parameterTypeNames }, new String[] { new String(problemMethod.closestMatch.declaringClass.shortReadableName()), new String(problemMethod.closestMatch.selector), closestParameterTypeShortNames, parameterTypeShortNames }, ProblemSeverities.Ignore, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition); return; } break; case ProblemReasons.NotVisible : id = IProblem.JavadocNotVisibleMethod; break; case ProblemReasons.Ambiguous : id = IProblem.JavadocAmbiguousMethod; break; case ProblemReasons.NoError : // 0 default : needImplementation(); // want to fail to see why we were here... break; } int severity = computeSeverity(id); if (severity == ProblemSeverities.Ignore) return; // report issue this.handle( id, new String[] { new String(method.declaringClass.readableName()), new String(method.selector), typesAsString(method.isVarargs(), method.parameters, false)}, new String[] { new String(method.declaringClass.shortReadableName()), new String(method.selector), typesAsString(method.isVarargs(), method.parameters, true)}, ProblemSeverities.Ignore, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition); } public void javadocInvalidParamTagName(int sourceStart, int sourceEnd) { this.handle(IProblem.JavadocInvalidParamTagName, NoArgument, NoArgument, sourceStart, sourceEnd); } public void javadocInvalidReference(int sourceStart, int sourceEnd) { this.handle(IProblem.JavadocInvalidSeeReference, NoArgument, NoArgument, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void javadocInvalidSeeReferenceArgs(int sourceStart, int sourceEnd) { this.handle(IProblem.JavadocInvalidSeeArgs, NoArgument, NoArgument, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void javadocInvalidSeeUrlReference(int sourceStart, int sourceEnd) { this.handle(IProblem.JavadocInvalidSeeHref, NoArgument, NoArgument, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void javadocInvalidTag(int sourceStart, int sourceEnd) { this.handle(IProblem.JavadocInvalidTag, NoArgument, NoArgument, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void javadocInvalidThrowsClass(int sourceStart, int sourceEnd) { this.handle(IProblem.JavadocInvalidThrowsClass, NoArgument, NoArgument, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void javadocInvalidThrowsClassName(TypeReference typeReference, int modifiers) { int severity = computeSeverity(IProblem.JavadocInvalidThrowsClassName); if (severity == ProblemSeverities.Ignore) return; if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) { String[] arguments = new String[] {String.valueOf(typeReference.resolvedType.sourceName())}; this.handle( IProblem.JavadocInvalidThrowsClassName, arguments, arguments, severity, typeReference.sourceStart, typeReference.sourceEnd); } } public void javadocInvalidType(ASTNode location, TypeBinding type, int modifiers) { if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) { int id = IProblem.JavadocUndefinedType; // default switch (type.problemId()) { case ProblemReasons.NotFound : id = IProblem.JavadocUndefinedType; break; case ProblemReasons.NotVisible : id = IProblem.JavadocNotVisibleType; break; case ProblemReasons.Ambiguous : id = IProblem.JavadocAmbiguousType; break; case ProblemReasons.InternalNameProvided : id = IProblem.JavadocInternalTypeNameProvided; break; case ProblemReasons.InheritedNameHidesEnclosingName : id = IProblem.JavadocInheritedNameHidesEnclosingTypeName; break; case ProblemReasons.NonStaticReferenceInStaticContext : id = IProblem.JavadocNonStaticTypeFromStaticInvocation; break; case ProblemReasons.NoError : // 0 default : needImplementation(); // want to fail to see why we were here... break; } int severity = computeSeverity(id); if (severity == ProblemSeverities.Ignore) return; this.handle( id, new String[] {new String(type.readableName())}, new String[] {new String(type.shortReadableName())}, ProblemSeverities.Ignore, location.sourceStart, location.sourceEnd); } } public void javadocMalformedSeeReference(int sourceStart, int sourceEnd) { this.handle(IProblem.JavadocMalformedSeeReference, NoArgument, NoArgument, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void javadocMissing(int sourceStart, int sourceEnd, int modifiers){ int severity = computeSeverity(IProblem.JavadocMissing); if (severity == ProblemSeverities.Ignore) return; boolean overriding = (modifiers & (ExtraCompilerModifiers.AccImplementing|ExtraCompilerModifiers.AccOverriding)) != 0; boolean report = (this.options.getSeverity(CompilerOptions.MissingJavadocComments) != ProblemSeverities.Ignore) && (!overriding || this.options.reportMissingJavadocCommentsOverriding); if (report) { String arg = javadocVisibilityArgument(this.options.reportMissingJavadocCommentsVisibility, modifiers); if (arg != null) { String[] arguments = new String[] { arg }; this.handle( IProblem.JavadocMissing, arguments, arguments, ProblemSeverities.Ignore, sourceStart, sourceEnd); } } } public void javadocMissingHashCharacter(int sourceStart, int sourceEnd, String ref){ int severity = computeSeverity(IProblem.JavadocMissingHashCharacter); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] { ref }; this.handle( IProblem.JavadocMissingHashCharacter, arguments, arguments, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void javadocMissingIdentifier(int sourceStart, int sourceEnd, int modifiers){ if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) this.handle(IProblem.JavadocMissingIdentifier, NoArgument, NoArgument, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void javadocMissingParamName(int sourceStart, int sourceEnd, int modifiers){ if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) this.handle(IProblem.JavadocMissingParamName, NoArgument, NoArgument, sourceStart, sourceEnd); } public void javadocMissingParamTag(char[] name, int sourceStart, int sourceEnd, int modifiers) { int severity = computeSeverity(IProblem.JavadocMissingParamTag); if (severity == ProblemSeverities.Ignore) return; boolean overriding = (modifiers & (ExtraCompilerModifiers.AccImplementing|ExtraCompilerModifiers.AccOverriding)) != 0; boolean report = (this.options.getSeverity(CompilerOptions.MissingJavadocTags) != ProblemSeverities.Ignore) && (!overriding || this.options.reportMissingJavadocTagsOverriding); if (report && javadocVisibility(this.options.reportMissingJavadocTagsVisibility, modifiers)) { String[] arguments = new String[] { String.valueOf(name) }; this.handle( IProblem.JavadocMissingParamTag, arguments, arguments, severity, sourceStart, sourceEnd); } } public void javadocMissingReference(int sourceStart, int sourceEnd, int modifiers){ if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) this.handle(IProblem.JavadocMissingSeeReference, NoArgument, NoArgument, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void javadocMissingReturnTag(int sourceStart, int sourceEnd, int modifiers){ boolean overriding = (modifiers & (ExtraCompilerModifiers.AccImplementing|ExtraCompilerModifiers.AccOverriding)) != 0; boolean report = (this.options.getSeverity(CompilerOptions.MissingJavadocTags) != ProblemSeverities.Ignore) && (!overriding || this.options.reportMissingJavadocTagsOverriding); if (report && javadocVisibility(this.options.reportMissingJavadocTagsVisibility, modifiers)) { this.handle(IProblem.JavadocMissingReturnTag, NoArgument, NoArgument, sourceStart, sourceEnd); } } public void javadocMissingThrowsClassName(int sourceStart, int sourceEnd, int modifiers){ if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) this.handle(IProblem.JavadocMissingThrowsClassName, NoArgument, NoArgument, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void javadocUndeclaredParamTagName(char[] token, int sourceStart, int sourceEnd, int modifiers) { int severity = computeSeverity(IProblem.JavadocInvalidParamName); if (severity == ProblemSeverities.Ignore) return; if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) { String[] arguments = new String[] {String.valueOf(token)}; this.handle( IProblem.JavadocInvalidParamName, arguments, arguments, severity, sourceStart, sourceEnd); } } public void javadocUnexpectedTag(int sourceStart, int sourceEnd) { this.handle(IProblem.JavadocUnexpectedTag, NoArgument, NoArgument, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void javadocUnexpectedText(int sourceStart, int sourceEnd) { this.handle(IProblem.JavadocUnexpectedText, NoArgument, NoArgument, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void javadocUnterminatedInlineTag(int sourceStart, int sourceEnd) { this.handle(IProblem.JavadocUnterminatedInlineTag, NoArgument, NoArgument, sourceStart, sourceEnd); } private boolean javadocVisibility(int visibility, int modifiers) { if (modifiers < 0) return true; switch (modifiers & ExtraCompilerModifiers.AccVisibilityMASK) { case ClassFileConstants.AccPublic : return true; case ClassFileConstants.AccProtected: return (visibility != ClassFileConstants.AccPublic); case ClassFileConstants.AccDefault: return (visibility == ClassFileConstants.AccDefault || visibility == ClassFileConstants.AccPrivate); case ClassFileConstants.AccPrivate: return (visibility == ClassFileConstants.AccPrivate); } return true; } private String javadocVisibilityArgument(int visibility, int modifiers) { String argument = null; switch (modifiers & ExtraCompilerModifiers.AccVisibilityMASK) { case ClassFileConstants.AccPublic : argument = CompilerOptions.PUBLIC; break; case ClassFileConstants.AccProtected: if (visibility != ClassFileConstants.AccPublic) { argument = CompilerOptions.PROTECTED; } break; case ClassFileConstants.AccDefault: if (visibility == ClassFileConstants.AccDefault || visibility == ClassFileConstants.AccPrivate) { argument = CompilerOptions.DEFAULT; } break; case ClassFileConstants.AccPrivate: if (visibility == ClassFileConstants.AccPrivate) { argument = CompilerOptions.PRIVATE; } break; } return argument; } public void localVariableHiding(LocalDeclaration local, Binding hiddenVariable, boolean isSpecialArgHidingField) { if (hiddenVariable instanceof LocalVariableBinding) { int id = (local instanceof Argument) ? IProblem.ArgumentHidingLocalVariable : IProblem.LocalVariableHidingLocalVariable; int severity = computeSeverity(id); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(local.name) }; this.handle( id, arguments, arguments, severity, nodeSourceStart(hiddenVariable, local), nodeSourceEnd(hiddenVariable, local)); } else if (hiddenVariable instanceof FieldBinding) { if (isSpecialArgHidingField && !this.options.reportSpecialParameterHidingField){ return; } int id = (local instanceof Argument) ? IProblem.ArgumentHidingField : IProblem.LocalVariableHidingField; int severity = computeSeverity(id); if (severity == ProblemSeverities.Ignore) return; FieldBinding field = (FieldBinding) hiddenVariable; this.handle( id, new String[] {new String(local.name) , new String(field.declaringClass.readableName()) }, new String[] {new String(local.name), new String(field.declaringClass.shortReadableName()) }, severity, local.sourceStart, local.sourceEnd); } } public void localVariableNonNullComparedToNull(LocalVariableBinding local, ASTNode location) { int severity = computeSeverity(IProblem.NonNullLocalVariableComparisonYieldsFalse); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(local.name) }; this.handle( IProblem.NonNullLocalVariableComparisonYieldsFalse, arguments, arguments, ProblemSeverities.Ignore, nodeSourceStart(local, location), nodeSourceEnd(local, location)); } public void localVariableNullComparedToNonNull(LocalVariableBinding local, ASTNode location) { int severity = computeSeverity(IProblem.NullLocalVariableComparisonYieldsFalse); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(local.name) }; this.handle( IProblem.NullLocalVariableComparisonYieldsFalse, arguments, arguments, ProblemSeverities.Ignore, nodeSourceStart(local, location), nodeSourceEnd(local, location)); } public void localVariableNullInstanceof(LocalVariableBinding local, ASTNode location) { int severity = computeSeverity(IProblem.NullLocalVariableInstanceofYieldsFalse); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(local.name) }; this.handle( IProblem.NullLocalVariableInstanceofYieldsFalse, arguments, arguments, ProblemSeverities.Ignore, nodeSourceStart(local, location), nodeSourceEnd(local, location)); } public void localVariableNullReference(LocalVariableBinding local, ASTNode location) { int severity = computeSeverity(IProblem.NullLocalVariableReference); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(local.name) }; this.handle( IProblem.NullLocalVariableReference, arguments, arguments, ProblemSeverities.Ignore, nodeSourceStart(local, location), nodeSourceEnd(local, location)); } public void localVariablePotentialNullReference(LocalVariableBinding local, ASTNode location) { int severity = computeSeverity(IProblem.PotentialNullLocalVariableReference); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(local.name)}; this.handle( IProblem.PotentialNullLocalVariableReference, arguments, arguments, ProblemSeverities.Ignore, nodeSourceStart(local, location), nodeSourceEnd(local, location)); } public void localVariableRedundantCheckOnNonNull(LocalVariableBinding local, ASTNode location) { int severity = computeSeverity(IProblem.RedundantNullCheckOnNonNullLocalVariable); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(local.name) }; this.handle( IProblem.RedundantNullCheckOnNonNullLocalVariable, arguments, arguments, ProblemSeverities.Ignore, nodeSourceStart(local, location), nodeSourceEnd(local, location)); } public void localVariableRedundantCheckOnNull(LocalVariableBinding local, ASTNode location) { int severity = computeSeverity(IProblem.RedundantNullCheckOnNullLocalVariable); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(local.name) }; this.handle( IProblem.RedundantNullCheckOnNullLocalVariable, arguments, arguments, ProblemSeverities.Ignore, nodeSourceStart(local, location), nodeSourceEnd(local, location)); } public void localVariableRedundantNullAssignment(LocalVariableBinding local, ASTNode location) { int severity = computeSeverity(IProblem.RedundantLocalVariableNullAssignment); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(local.name) }; this.handle( IProblem.RedundantLocalVariableNullAssignment, arguments, arguments, ProblemSeverities.Ignore, nodeSourceStart(local, location), nodeSourceEnd(local, location)); } public void missingReturnType(AbstractMethodDeclaration methodDecl) { this.handle( IProblem.MissingReturnType, NoArgument, NoArgument, ProblemSeverities.Ignore, methodDecl.sourceStart, methodDecl.sourceEnd); } public void missingSemiColon(Expression expression, int start, int end){ this.handle( IProblem.MissingSemiColon, NoArgument, NoArgument, start, end); } public void mustUseAStaticMethod(ASTNode messageSend, MethodBinding method) { this.handle( IProblem.StaticMethodRequested, new String[] {new String(method.declaringClass.readableName()), new String(method.selector != null ? method.selector : "".toCharArray()), typesAsString(method.isVarargs(), method.parameters, false)}, new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector != null ? method.selector : "".toCharArray()), typesAsString(method.isVarargs(), method.parameters, true)}, ProblemSeverities.Ignore, messageSend.sourceStart, messageSend.sourceEnd); } public void needImplementation() { this.abortDueToInternalError(Messages.abort_missingCode); } private int nodeSourceEnd(Binding field, ASTNode node) { return nodeSourceEnd(field, node, 0); } private int nodeSourceEnd(Binding field, ASTNode node, int index) { if (node instanceof ArrayTypeReference) { return ((ArrayTypeReference) node).originalSourceEnd; } else if (node instanceof QualifiedNameReference) { QualifiedNameReference ref = (QualifiedNameReference) node; if (ref.binding == field) { return (int) (ref.sourcePositions[ref.indexOfFirstFieldBinding-1]); } FieldBinding[] otherFields = ref.otherBindings; if (otherFields != null) { int offset = ref.indexOfFirstFieldBinding; for (int i = 0, length = otherFields.length; i < length; i++) { if (otherFields[i] == field) return (int) (ref.sourcePositions[i + offset]); } } } else if (node instanceof ArrayQualifiedTypeReference) { ArrayQualifiedTypeReference arrayQualifiedTypeReference = (ArrayQualifiedTypeReference) node; int length = arrayQualifiedTypeReference.sourcePositions.length; return (int) arrayQualifiedTypeReference.sourcePositions[length - 1]; } return node.sourceEnd; } private int nodeSourceStart(Binding field, ASTNode node) { if (node instanceof FieldReference) { FieldReference fieldReference = (FieldReference) node; return (int) (fieldReference.nameSourcePosition >> 32); } else if (node instanceof QualifiedNameReference) { QualifiedNameReference ref = (QualifiedNameReference) node; if (ref.binding == field) { return (int) (ref.sourcePositions[ref.indexOfFirstFieldBinding-1] >> 32); } FieldBinding[] otherFields = ref.otherBindings; if (otherFields != null) { int offset = ref.indexOfFirstFieldBinding; for (int i = 0, length = otherFields.length; i < length; i++) { if (otherFields[i] == field) return (int) (ref.sourcePositions[i + offset] >> 32); } } } return node.sourceStart; } public void noMoreAvailableSpaceForArgument(LocalVariableBinding local, ASTNode location) { String[] arguments = new String[]{ new String(local.name) }; this.handle( IProblem.TooManyArgumentSlots, arguments, arguments, ProblemSeverities.Ignore, nodeSourceStart(local, location), nodeSourceEnd(local, location)); } public void noMoreAvailableSpaceForLocal(LocalVariableBinding local, ASTNode location) { String[] arguments = new String[]{ new String(local.name) }; this.handle( IProblem.TooManyLocalVariableSlots, arguments, arguments, ProblemSeverities.Ignore, nodeSourceStart(local, location), nodeSourceEnd(local, location)); } public void nonExternalizedStringLiteral(ASTNode location) { this.handle( IProblem.NonExternalizedStringLiteral, NoArgument, NoArgument, location.sourceStart, location.sourceEnd); } public void nonStaticAccessToStaticField(ASTNode location, FieldBinding field) { int severity = computeSeverity(IProblem.NonStaticAccessToStaticField); if (severity == ProblemSeverities.Ignore) return; this.handle( IProblem.NonStaticAccessToStaticField, new String[] {new String(field.declaringClass.readableName()), new String(field.name)}, new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)}, ProblemSeverities.Ignore, nodeSourceStart(field, location), nodeSourceEnd(field, location)); } public void nonStaticAccessToStaticMethod(ASTNode location, MethodBinding method) { this.handle( IProblem.NonStaticAccessToStaticMethod, new String[] {new String(method.declaringClass.readableName()), new String(method.selector), typesAsString(method.isVarargs(), method.parameters, false)}, new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), typesAsString(method.isVarargs(), method.parameters, true)}, ProblemSeverities.Ignore, location.sourceStart, location.sourceEnd); } public void looseVariableDecleration(ASTNode location, Assignment assignment) { String[] arguments = new String[] {assignment.lhs.toString()}; this.handle( IProblem.LooseVarDecl, arguments, arguments, assignment.sourceStart, assignment.sourceEnd); } public void optionalSemicolon(ASTNode location) { // Do something else System.out.println("Optional Semi"); //$NON-NLS-1$ } public void notCompatibleTypesError(InstanceOfExpression expression, TypeBinding leftType, TypeBinding rightType) { String leftName = new String(leftType.readableName()); String rightName = new String(rightType.readableName()); String leftShortName = new String(leftType.shortReadableName()); String rightShortName = new String(rightType.shortReadableName()); if (leftShortName.equals(rightShortName)){ leftShortName = leftName; rightShortName = rightName; } this.handle( IProblem.IncompatibleTypesInConditionalOperator, new String[] {leftName, rightName }, new String[] {leftShortName, rightShortName }, ProblemSeverities.Ignore, expression.sourceStart, expression.sourceEnd); } public void operatorOnlyValidOnNumericType(CompoundAssignment assignment, TypeBinding leftType, TypeBinding rightType) { String leftName = new String(leftType.readableName()); String rightName = new String(rightType.readableName()); String leftShortName = new String(leftType.shortReadableName()); String rightShortName = new String(rightType.shortReadableName()); if (leftShortName.equals(rightShortName)){ leftShortName = leftName; rightShortName = rightName; } this.handle( IProblem.TypeMismatch, new String[] {leftName, rightName }, new String[] {leftShortName, rightShortName }, ProblemSeverities.Ignore, assignment.sourceStart, assignment.sourceEnd); } public void overridesDeprecatedMethod(MethodBinding localMethod, MethodBinding inheritedMethod) { this.handle( IProblem.OverridingDeprecatedMethod, new String[] { new String( CharOperation.concat( localMethod.declaringClass.readableName(), localMethod.readableName(), '.')), new String(inheritedMethod.declaringClass.readableName())}, new String[] { new String( CharOperation.concat( localMethod.declaringClass.shortReadableName(), localMethod.shortReadableName(), '.')), new String(inheritedMethod.declaringClass.shortReadableName())}, ProblemSeverities.Ignore, localMethod.sourceStart(), localMethod.sourceEnd()); } public void parameterAssignment(LocalVariableBinding local, ASTNode location) { int severity = computeSeverity(IProblem.ParameterAssignment); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] { new String(local.readableName())}; this.handle( IProblem.ParameterAssignment, arguments, arguments, severity, nodeSourceStart(local, location), nodeSourceEnd(local, location)); // should never be a qualified name reference } public void parseError( int startPosition, int endPosition, int currentToken, char[] currentTokenSource, String errorTokenName, String[] possibleTokens) { if (possibleTokens.length == 0) { //no suggestion available if (isKeyword(currentToken)) { String[] arguments = new String[] {new String(currentTokenSource)}; this.handle( IProblem.ParsingErrorOnKeywordNoSuggestion, arguments, arguments, // this is the current -invalid- token position startPosition, endPosition); return; } else { String[] arguments = new String[] {errorTokenName}; this.handle( IProblem.ParsingErrorNoSuggestion, arguments, arguments, // this is the current -invalid- token position startPosition, endPosition); return; } } //build a list of probable right tokens StringBuffer list = new StringBuffer(20); for (int i = 0, max = possibleTokens.length; i < max; i++) { if (i > 0) list.append(", "); //$NON-NLS-1$ list.append('"'); list.append(possibleTokens[i]); list.append('"'); } if (isKeyword(currentToken)) { String[] arguments = new String[] {new String(currentTokenSource), list.toString()}; this.handle( IProblem.ParsingErrorOnKeyword, arguments, arguments, // this is the current -invalid- token position startPosition, endPosition); return; } //extract the literal when it's a literal if (isLiteral(currentToken) || isIdentifier(currentToken)) { errorTokenName = new String(currentTokenSource); } String[] arguments = new String[] {errorTokenName, list.toString()}; this.handle( IProblem.ParsingError, arguments, arguments, // this is the current -invalid- token position startPosition, endPosition); } public void parseErrorDeleteToken( int start, int end, int currentKind, char[] errorTokenSource, String errorTokenName){ this.syntaxError( IProblem.ParsingErrorDeleteToken, start, end, currentKind, errorTokenSource, errorTokenName, null); } public void parseErrorDeleteTokens( int start, int end){ this.handle( IProblem.ParsingErrorDeleteTokens, NoArgument, NoArgument, start, end); } public void parseErrorInsertAfterToken( int start, int end, int currentKind, char[] errorTokenSource, String errorTokenName, String expectedToken){ this.syntaxError( IProblem.ParsingErrorInsertTokenAfter, start, end, currentKind, errorTokenSource, errorTokenName, expectedToken); } public void parseErrorInsertBeforeToken( int start, int end, int currentKind, char[] errorTokenSource, String errorTokenName, String expectedToken){ this.syntaxError( IProblem.ParsingErrorInsertTokenBefore, start, end, currentKind, errorTokenSource, errorTokenName, expectedToken); } public void parseErrorInsertToComplete( int start, int end, String inserted, String completed){ String[] arguments = new String[] {inserted, completed}; if (";".equals(inserted)) // ignore missing semicolon error //$NON-NLS-1$ return; this.handle( IProblem.ParsingErrorInsertToComplete, arguments, arguments, start, end); } public void parseErrorInsertToCompletePhrase( int start, int end, String inserted){ String[] arguments = new String[] {inserted}; this.handle( IProblem.ParsingErrorInsertToCompletePhrase, arguments, arguments, start, end); } public void parseErrorInsertToCompleteScope( int start, int end, String inserted){ String[] arguments = new String[] {inserted}; this.handle( IProblem.ParsingErrorInsertToCompleteScope, arguments, arguments, start, end); } public void parseErrorInvalidToken( int start, int end, int currentKind, char[] errorTokenSource, String errorTokenName, String expectedToken){ this.syntaxError( IProblem.ParsingErrorInvalidToken, start, end, currentKind, errorTokenSource, errorTokenName, expectedToken); } public void parseErrorMergeTokens( int start, int end, String expectedToken){ String[] arguments = new String[] {expectedToken}; this.handle( IProblem.ParsingErrorMergeTokens, arguments, arguments, start, end); } public void parseErrorMisplacedConstruct( int start, int end){ this.handle( IProblem.ParsingErrorMisplacedConstruct, NoArgument, NoArgument, start, end); } public void parseErrorNoSuggestion( int start, int end, int currentKind, char[] errorTokenSource, String errorTokenName){ this.syntaxError( IProblem.ParsingErrorNoSuggestion, start, end, currentKind, errorTokenSource, errorTokenName, null); } public void parseErrorNoSuggestionForTokens( int start, int end){ this.handle( IProblem.ParsingErrorNoSuggestionForTokens, NoArgument, NoArgument, start, end); } public void parseErrorReplaceToken( int start, int end, int currentKind, char[] errorTokenSource, String errorTokenName, String expectedToken){ this.syntaxError( IProblem.ParsingError, start, end, currentKind, errorTokenSource, errorTokenName, expectedToken); } public void parseErrorReplaceTokens( int start, int end, String expectedToken){ String[] arguments = new String[] {expectedToken}; this.handle( IProblem.ParsingErrorReplaceTokens, arguments, arguments, start, end); } public void parseErrorUnexpectedEnd( int start, int end){ String[] arguments; if(this.referenceContext instanceof ConstructorDeclaration) { arguments = new String[] {Messages.parser_endOfConstructor}; } else if(this.referenceContext instanceof MethodDeclaration) { arguments = new String[] {Messages.parser_endOfMethod}; } else if(this.referenceContext instanceof TypeDeclaration) { arguments = new String[] {Messages.parser_endOfInitializer}; } else { arguments = new String[] {Messages.parser_endOfFile}; } this.handle( IProblem.ParsingErrorUnexpectedEOF, arguments, arguments, start, end); } public void possibleAccidentalBooleanAssignment(Assignment assignment) { this.handle( IProblem.PossibleAccidentalBooleanAssignment, NoArgument, NoArgument, ProblemSeverities.Ignore, assignment.sourceStart, assignment.sourceEnd); } public void possibleFallThroughCase(CaseStatement caseStatement) { // as long as we consider fake reachable as reachable, better keep 'possible' in the name this.handle( IProblem.FallthroughCase, NoArgument, NoArgument, caseStatement.sourceStart, caseStatement.sourceEnd); } public void redefineArgument(Argument arg) { String[] arguments = new String[] {new String(arg.name)}; this.handle( IProblem.RedefinedArgument, arguments, arguments, ProblemSeverities.Ignore, arg.sourceStart, arg.sourceEnd); } public void redefineLocal(LocalDeclaration localDecl) { String[] arguments = new String[] {new String(localDecl.name)}; this.handle( IProblem.RedefinedLocal, arguments, arguments, ProblemSeverities.Ignore, localDecl.sourceStart, localDecl.sourceEnd); } public void reset() { this.positionScanner = null; } private int retrieveEndingPositionAfterOpeningParenthesis(int sourceStart, int sourceEnd, int numberOfParen) { if (this.referenceContext == null) return sourceEnd; CompilationResult compilationResult = this.referenceContext.compilationResult(); if (compilationResult == null) return sourceEnd; ICompilationUnit compilationUnit = compilationResult.getCompilationUnit(); if (compilationUnit == null) return sourceEnd; char[] contents = compilationUnit.getContents(); if (contents.length == 0) return sourceEnd; if (this.positionScanner == null) { this.positionScanner = new Scanner(false, false, false, this.options.sourceLevel, this.options.complianceLevel, null, null, false); } this.positionScanner.setSource(contents); this.positionScanner.resetTo(sourceStart, sourceEnd); try { int token; int previousSourceEnd = sourceEnd; while ((token = this.positionScanner.getNextToken()) != TerminalTokens.TokenNameEOF) { switch(token) { case TerminalTokens.TokenNameRPAREN: return previousSourceEnd; default : previousSourceEnd = this.positionScanner.currentPosition - 1; } } } catch(InvalidInputException e) { // ignore } return sourceEnd; } private int retrieveStartingPositionAfterOpeningParenthesis(int sourceStart, int sourceEnd, int numberOfParen) { if (this.referenceContext == null) return sourceStart; CompilationResult compilationResult = this.referenceContext.compilationResult(); if (compilationResult == null) return sourceStart; ICompilationUnit compilationUnit = compilationResult.getCompilationUnit(); if (compilationUnit == null) return sourceStart; char[] contents = compilationUnit.getContents(); if (contents.length == 0) return sourceStart; if (this.positionScanner == null) { this.positionScanner = new Scanner(false, false, false, this.options.sourceLevel, this.options.complianceLevel, null, null, false); } this.positionScanner.setSource(contents); this.positionScanner.resetTo(sourceStart, sourceEnd); int count = 0; try { int token; while ((token = this.positionScanner.getNextToken()) != TerminalTokens.TokenNameEOF) { switch(token) { case TerminalTokens.TokenNameLPAREN: count++; if (count == numberOfParen) { this.positionScanner.getNextToken(); return this.positionScanner.startPosition; } } } } catch(InvalidInputException e) { // ignore } return sourceStart; } public void scannerError(Parser parser, String errorTokenName) { Scanner scanner = parser.scanner; int flag = IProblem.ParsingErrorNoSuggestion; int startPos = scanner.startPosition; int endPos = scanner.currentPosition - 1; //special treatment for recognized errors.... if (errorTokenName.equals(Scanner.END_OF_SOURCE)) flag = IProblem.EndOfSource; else if (errorTokenName.equals(Scanner.INVALID_HEXA)) flag = IProblem.InvalidHexa; else if (errorTokenName.equals(Scanner.INVALID_OCTAL)) flag = IProblem.InvalidOctal; else if (errorTokenName.equals(Scanner.INVALID_CHARACTER_CONSTANT)) flag = IProblem.InvalidCharacterConstant; else if (errorTokenName.equals(Scanner.INVALID_ESCAPE)) flag = IProblem.InvalidEscape; else if (errorTokenName.equals(Scanner.INVALID_UNICODE_ESCAPE)){ flag = IProblem.InvalidUnicodeEscape; // better locate the error message char[] source = scanner.source; int checkPos = scanner.currentPosition - 1; if (checkPos >= source.length) checkPos = source.length - 1; while (checkPos >= startPos){ if (source[checkPos] == '\\') break; checkPos --; } startPos = checkPos; } else if (errorTokenName.equals(Scanner.INVALID_LOW_SURROGATE)) { flag = IProblem.InvalidLowSurrogate; } else if (errorTokenName.equals(Scanner.INVALID_HIGH_SURROGATE)) { flag = IProblem.InvalidHighSurrogate; // better locate the error message char[] source = scanner.source; int checkPos = scanner.startPosition + 1; while (checkPos <= endPos){ if (source[checkPos] == '\\') break; checkPos ++; } endPos = checkPos - 1; } else if (errorTokenName.equals(Scanner.INVALID_FLOAT)) flag = IProblem.InvalidFloat; else if (errorTokenName.equals(Scanner.UNTERMINATED_STRING)) flag = IProblem.UnterminatedString; else if (errorTokenName.equals(Scanner.UNTERMINATED_COMMENT)) flag = IProblem.UnterminatedComment; else if (errorTokenName.equals(Scanner.INVALID_CHAR_IN_STRING)) flag = IProblem.UnterminatedString; else if (errorTokenName.equals(Scanner.INVALID_DIGIT)) flag = IProblem.InvalidDigit; String[] arguments = flag == IProblem.ParsingErrorNoSuggestion ? new String[] {errorTokenName} : NoArgument; this.handle( flag, arguments, arguments, // this is the current -invalid- token position startPos, endPos, parser.compilationUnit.compilationResult); } public void shouldReturn(TypeBinding returnType, ASTNode location) { this.handle( IProblem.ShouldReturnValue, new String[] { new String (returnType.readableName())}, new String[] { new String (returnType.shortReadableName())}, ProblemSeverities.Ignore, location.sourceStart, location.sourceEnd); } public void staticAndInstanceConflict(MethodBinding currentMethod, MethodBinding inheritedMethod) { if (currentMethod.isStatic()) this.handle( // This static method cannot hide the instance method from %1 // 8.4.6.4 - If a class inherits more than one method with the same signature a static (non-abstract) method cannot hide an instance method. IProblem.CannotHideAnInstanceMethodWithAStaticMethod, new String[] {new String(inheritedMethod.declaringClass.readableName())}, new String[] {new String(inheritedMethod.declaringClass.shortReadableName())}, ProblemSeverities.Ignore, currentMethod.sourceStart(), currentMethod.sourceEnd()); else this.handle( // This instance method cannot override the static method from %1 // 8.4.6.4 - If a class inherits more than one method with the same signature an instance (non-abstract) method cannot override a static method. IProblem.CannotOverrideAStaticMethodWithAnInstanceMethod, new String[] {new String(inheritedMethod.declaringClass.readableName())}, new String[] {new String(inheritedMethod.declaringClass.shortReadableName())}, currentMethod.sourceStart(), currentMethod.sourceEnd()); } public void staticFieldAccessToNonStaticVariable(ASTNode location, FieldBinding field) { String[] arguments = new String[] {new String(field.readableName())}; this.handle( IProblem.NonStaticFieldFromStaticInvocation, arguments, arguments, ProblemSeverities.Ignore, nodeSourceStart(field,location), nodeSourceEnd(field, location)); } public void superfluousSemicolon(int sourceStart, int sourceEnd) { this.handle( IProblem.SuperfluousSemicolon, NoArgument, NoArgument, sourceStart, sourceEnd); } private void syntaxError( int id, int startPosition, int endPosition, int currentKind, char[] currentTokenSource, String errorTokenName, String expectedToken) { String eTokenName; if (isKeyword(currentKind) || isLiteral(currentKind) || isIdentifier(currentKind)) { eTokenName = new String(currentTokenSource); } else { eTokenName = errorTokenName; } String[] arguments; if(expectedToken != null) { arguments = new String[] {eTokenName, expectedToken}; } else { arguments = new String[] {eTokenName}; } this.handle( id, arguments, arguments, startPosition, endPosition); } public void task(String tag, String message, String priority, int start, int end){ this.handle( IProblem.Task, new String[] { tag, message, priority/*secret argument that is not surfaced in getMessage()*/}, new String[] { tag, message, priority/*secret argument that is not surfaced in getMessage()*/}, start, end); } public void typeMismatchError(TypeBinding actualType, TypeBinding expectedType, ASTNode location) { this.handle( IProblem.TypeMismatch, new String[] {new String(actualType.readableName()), new String(expectedType.readableName())}, new String[] {new String(actualType.shortReadableName()), new String(expectedType.shortReadableName())}, location.sourceStart, location.sourceEnd); } private String typesAsString(boolean isVarargs, TypeBinding[] types, boolean makeShort) { StringBuffer buffer = new StringBuffer(10); for (int i = 0, length = types.length; i < length; i++) { if (i != 0) buffer.append(", "); //$NON-NLS-1$ TypeBinding type = types[i]; boolean isVarargType = isVarargs && i == length-1; if (isVarargType) type = ((ArrayBinding)type).elementsType(); buffer.append(new String(makeShort ? type.shortReadableName() : type.readableName())); if (isVarargType) buffer.append("..."); //$NON-NLS-1$ } return buffer.toString(); } public void undefinedLabel(BranchStatement statement) { if (isRecoveredName(statement.label)) return; String[] arguments = new String[] {new String(statement.label)}; this.handle( IProblem.UndefinedLabel, arguments, arguments, statement.sourceStart, statement.sourceEnd); } public void undocumentedEmptyBlock(int blockStart, int blockEnd) { this.handle( IProblem.UndocumentedEmptyBlock, NoArgument, NoArgument, blockStart, blockEnd); } public void uninitializedLocalVariable(LocalVariableBinding binding, ASTNode location) { int severity = computeSeverity(IProblem.UninitializedLocalVariable); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(binding.readableName())}; this.handle( IProblem.UninitializedLocalVariable, arguments, arguments, severity, nodeSourceStart(binding, location), nodeSourceEnd(binding, location)); } public void uninitializedGlobalVariable(LocalVariableBinding binding, ASTNode location) { int severity = computeSeverity(IProblem.UninitializedGlobalVariable); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(binding.readableName())}; this.handle( IProblem.UninitializedGlobalVariable, arguments, arguments, ProblemSeverities.Ignore, nodeSourceStart(binding, location), nodeSourceEnd(binding, location)); } public void unnecessaryElse(ASTNode location) { this.handle( IProblem.UnnecessaryElse, NoArgument, NoArgument, location.sourceStart, location.sourceEnd); } public void unnecessaryNLSTags(int sourceStart, int sourceEnd) { this.handle( IProblem.UnnecessaryNLSTag, NoArgument, NoArgument, sourceStart, sourceEnd); } public void unreachableCode(Statement statement) { int sourceStart = statement.sourceStart; int sourceEnd = statement.sourceEnd; if (statement instanceof LocalDeclaration) { LocalDeclaration declaration = (LocalDeclaration) statement; sourceStart = declaration.declarationSourceStart; sourceEnd = declaration.declarationSourceEnd; } else if (statement instanceof Expression) { int statemendEnd = ((Expression) statement).statementEnd; if (statemendEnd != -1) sourceEnd = statemendEnd; } this.handle( IProblem.CodeCannotBeReached, NoArgument, NoArgument, ProblemSeverities.Ignore, sourceStart, sourceEnd); } public void unresolvableReference(NameReference nameRef, Binding binding) { /* also need to check that the searchedType is the receiver type if (binding instanceof ProblemBinding) { ProblemBinding problem = (ProblemBinding) binding; if (problem.searchType != null && problem.searchType.isHierarchyInconsistent()) severity = SecondaryError; } */ String[] arguments = new String[] {new String(binding.readableName())}; int end = nameRef.sourceEnd; if (nameRef instanceof QualifiedNameReference) { QualifiedNameReference ref = (QualifiedNameReference) nameRef; if (isRecoveredName(ref.tokens)) return; if (ref.indexOfFirstFieldBinding >= 1) end = (int) ref.sourcePositions[ref.indexOfFirstFieldBinding - 1]; } else { SingleNameReference ref = (SingleNameReference) nameRef; if (isRecoveredName(ref.token)) return; } this.handle( IProblem.UndefinedName, arguments, arguments, ProblemSeverities.Ignore, nameRef.sourceStart, end); } public void unusedArgument(LocalDeclaration localDecl) { int severity = computeSeverity(IProblem.ArgumentIsNeverUsed); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(localDecl.name)}; this.handle( IProblem.ArgumentIsNeverUsed, arguments, arguments, ProblemSeverities.Ignore, localDecl.sourceStart, localDecl.sourceEnd); } public void unusedLabel(LabeledStatement statement) { int severity = computeSeverity(IProblem.UnusedLabel); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(statement.label)}; this.handle( IProblem.UnusedLabel, arguments, arguments, ProblemSeverities.Ignore, statement.sourceStart, statement.labelEnd); } public void unusedLocalVariable(LocalDeclaration localDecl) { int severity = computeSeverity(IProblem.LocalVariableIsNeverUsed); if (severity == ProblemSeverities.Ignore) return; String[] arguments = new String[] {new String(localDecl.name)}; this.handle( IProblem.LocalVariableIsNeverUsed, arguments, arguments, severity, localDecl.sourceStart, localDecl.sourceEnd); } public void unusedPrivateField(FieldDeclaration fieldDecl) { int severity = computeSeverity(IProblem.UnusedPrivateField); if (severity == ProblemSeverities.Ignore) return; FieldBinding field = fieldDecl.binding; this.handle( IProblem.UnusedPrivateField, new String[] { new String(field.declaringClass.readableName()), new String(field.name), }, new String[] { new String(field.declaringClass.shortReadableName()), new String(field.name), }, ProblemSeverities.Ignore, nodeSourceStart(field, fieldDecl), nodeSourceEnd(field, fieldDecl)); } public void unusedPrivateMethod(AbstractMethodDeclaration methodDecl) { int severity = computeSeverity(IProblem.UnusedPrivateMethod); if (severity == ProblemSeverities.Ignore) return; MethodBinding method = methodDecl.binding; char[] methodSelector = method.selector; if(methodSelector == null) methodSelector = methodDecl.getSafeName(); // no report for serialization support 'Object readResolve()' if (!method.isStatic() && TypeIds.T_JavaLangObject == method.returnType.id && method.parameters.length == 0 && CharOperation.equals(methodSelector, TypeConstants.READRESOLVE)) { return; } // no report for serialization support 'Object writeReplace()' if (!method.isStatic() && TypeIds.T_JavaLangObject == method.returnType.id && method.parameters.length == 0 && CharOperation.equals(methodSelector, TypeConstants.WRITEREPLACE)) { return; } this.handle( IProblem.UnusedPrivateMethod, new String[] { new String(method.declaringClass.readableName()), new String(methodSelector), typesAsString(method.isVarargs(), method.parameters, false) }, new String[] { new String(method.declaringClass.shortReadableName()), new String(methodSelector), typesAsString(method.isVarargs(), method.parameters, true) }, ProblemSeverities.Ignore, methodDecl.sourceStart, methodDecl.sourceEnd); } public void unusedPrivateType(TypeDeclaration typeDecl) { int severity = computeSeverity(IProblem.UnusedPrivateType); if (severity == ProblemSeverities.Ignore) return; ReferenceBinding type = typeDecl.binding; this.handle( IProblem.UnusedPrivateType, new String[] { new String(type.readableName()), }, new String[] { new String(type.shortReadableName()), }, ProblemSeverities.Ignore, typeDecl.sourceStart, typeDecl.sourceEnd); } public void visibilityConflict(MethodBinding currentMethod, MethodBinding inheritedMethod) { this.handle( // Cannot reduce the visibility of the inherited method from %1 // 8.4.6.3 - The access modifier of an hiding method must provide at least as much access as the hidden method. // 8.4.6.3 - The access modifier of an overiding method must provide at least as much access as the overriden method. IProblem.MethodReducesVisibility, new String[] {new String(inheritedMethod.declaringClass.readableName())}, new String[] {new String(inheritedMethod.declaringClass.shortReadableName())}, ProblemSeverities.Ignore, currentMethod.sourceStart(), currentMethod.sourceEnd()); } }