@Override public boolean validate(IAcceptor<? super AbstractDiagnostic> result) { JvmDeclaredType declaringType = getConstructor().getDeclaringType(); if (declaringType.isAbstract()) { String message = "Cannot instantiate the abstract type " + declaringType.getSimpleName(); AbstractDiagnostic diagnostic = new EObjectDiagnosticImpl( Severity.ERROR, IssueCodes.ABSTRACT_CLASS_INSTANTIATION, message, getExpression(), getDefaultValidationFeature(), -1, null); result.accept(diagnostic); return false; } return super.validate(result); }
@Override public boolean validate(IAcceptor<? super AbstractDiagnostic> result) { if (chosenCandidate.validate(result)) { StringBuilder messageBuilder = new StringBuilder("Suspiciously overloaded method.\n"); messageBuilder.append("The ").append(getFeatureTypeName()).append("\n\t"); appendCandidate(chosenCandidate, messageBuilder); messageBuilder.append("\noverloads the ").append(getFeatureTypeName()).append("\n\t"); appendCandidate(rejectedCandidate, messageBuilder); messageBuilder.append("."); AbstractDiagnostic diagnostic = new EObjectDiagnosticImpl(chosenCandidate.getSeverity(IssueCodes.SUSPICIOUSLY_OVERLOADED_FEATURE), IssueCodes.SUSPICIOUSLY_OVERLOADED_FEATURE, messageBuilder.toString(), getExpression(), XbasePackage.Literals.XABSTRACT_FEATURE_CALL__FEATURE, -1, null); result.accept(diagnostic); } return false; }
@Override public boolean validate(IAcceptor<? super AbstractDiagnostic> result) { if (!getState().isInstanceContext()) { JvmIdentifiableElement implicitFeature = getFeature(); if (implicitFeature instanceof JvmType) { JvmIdentifiableElement feature = getState().getResolvedTypes().getLinkedFeature(getOwner()); if (feature == null || feature.eIsProxy() || !(feature instanceof JvmFeature)) return true; String message = "Cannot make an implicit reference to this from a static context"; AbstractDiagnostic diagnostic = new EObjectDiagnosticImpl(Severity.ERROR, IssueCodes.STATIC_ACCESS_TO_INSTANCE_MEMBER, message, getOwner(), XbasePackage.Literals.XABSTRACT_FEATURE_CALL__FEATURE, -1, null); result.accept(diagnostic); return false; } } return super.validate(result); }
protected AbstractDiagnostic createTypeDiagnostic(XExpression expression, LightweightTypeReference actualType, LightweightTypeReference expectedType) { if (!expectedType.isAny()) { String actualName = actualType.getSimpleName(); String expectedName = expectedType.getSimpleName(); if (actualName.equals(expectedName)) { if (expectedType.isAssignableFrom(actualType)) { return null; } } if (expression.eContainingFeature() == XbasePackage.Literals.XABSTRACT_FEATURE_CALL__IMPLICIT_FIRST_ARGUMENT) { return new EObjectDiagnosticImpl(Severity.ERROR, IssueCodes.INCOMPATIBLE_TYPES, String.format( "Type mismatch: cannot convert implicit first argument from %s to %s", actualType.getHumanReadableName(), expectedType.getHumanReadableName()), expression, null, -1, null); } else { return new EObjectDiagnosticImpl(Severity.ERROR, IssueCodes.INCOMPATIBLE_TYPES, String.format( "Type mismatch: cannot convert from %s to %s", actualType.getHumanReadableName(), expectedType.getHumanReadableName()), expression, null, -1, null); } } else { return new EObjectDiagnosticImpl(Severity.ERROR, IssueCodes.INCOMPATIBLE_TYPES, String.format( "Type mismatch: type %s is not applicable at this location", actualType.getHumanReadableName()), expression, null, -1, null); } }
/** * Validates this linking candidate and adds respective diagnostics to the given queue. * * This checks the following criteria: * <ol> * <li>{@link #validateVisibility(IAcceptor) visibility},</li> * <li>{@link #validateArity(IAcceptor) arity},</li> * <li>{@link #validateTypeArity(IAcceptor) type arity},</li> * <li>{@link #validateTypeArgumentConformance(IAcceptor) type arguments},</li> * <li>{@link #validateUnhandledExceptions(IAcceptor) unhandled excptions},</li> * </ol> */ @Override public boolean validate(IAcceptor<? super AbstractDiagnostic> result) { if (!validateVisibility(result)) { return false; } if (!validateArity(result)) { return false; } if (!validateTypeArity(result)) { return false; } if (!validateTypeArgumentConformance(result)) { return false; } if (!validateUnhandledExceptions(result)) { return false; } return true; }
protected boolean validateVisibility(IAcceptor<? super AbstractDiagnostic> result) { if (!isVisible()) { String message = String.format("The %1$s %2$s%3$s is not visible", getFeatureTypeName(), getSimpleFeatureName(), getFeatureParameterTypesAsString()); AbstractDiagnostic diagnostic = new EObjectDiagnosticImpl( Severity.ERROR, IssueCodes.FEATURE_NOT_VISIBLE, message, getExpression(), getDefaultValidationFeature(), -1, null); result.accept(diagnostic); return false; } return true; }
protected boolean validateArity(IAcceptor<? super AbstractDiagnostic> result) { if (getArityMismatch() != 0) { String message; if (getArguments().isEmpty()) { message = String.format("Invalid number of arguments. The %1$s %2$s%3$s is not applicable without arguments" , getFeatureTypeName(), getSimpleFeatureName(), getFeatureParameterTypesAsString()); } else { message = String.format("Invalid number of arguments. The %1$s %2$s%3$s is not applicable for the arguments %4$s" , getFeatureTypeName(), getSimpleFeatureName(), getFeatureParameterTypesAsString(), getArgumentTypesAsString()); } AbstractDiagnostic diagnostic = new EObjectDiagnosticImpl( Severity.ERROR, IssueCodes.INVALID_NUMBER_OF_ARGUMENTS, message, getExpression(), getInvalidArgumentsValidationFeature(), -1, null); result.accept(diagnostic); return false; } return true; }
protected boolean validateTypeArity(IAcceptor<? super AbstractDiagnostic> result) { if (getTypeArityMismatch() != 0) { String message = String.format("Invalid number of type arguments. The %1$s %2$s%3$s is not applicable for the type arguments %4$s", getFeatureTypeName(), getSimpleFeatureName(), getFeatureTypeParametersAsString(true), getTypeArgumentsAsString(getSyntacticTypeArguments())); AbstractDiagnostic diagnostic = new EObjectDiagnosticImpl( Severity.ERROR, IssueCodes.INVALID_NUMBER_OF_TYPE_ARGUMENTS, message, getExpression(), getDefaultValidationFeature(), -1, null); result.accept(diagnostic); return false; } return true; }
@Override public boolean validate(IAcceptor<? super AbstractDiagnostic> result) { JvmType type = (JvmType) description.getElementOrProxy(); String typeKind = ""; if (type instanceof JvmPrimitiveType || type instanceof JvmVoid) { typeKind = "primitive type"; } else if (type instanceof JvmAnnotationType) { typeKind = "annotation type"; } else if (type instanceof JvmEnumerationType) { typeKind = "enum type"; } else if (type instanceof JvmGenericType && ((JvmGenericType) type).isInterface()) { typeKind = "interface type"; } else if (type instanceof JvmTypeParameter) { typeKind = "type parameter"; } String message = String.format("Cannot instantiate the %s %s", typeKind, type.getSimpleName()); AbstractDiagnostic diagnostic = new EObjectDiagnosticImpl(Severity.ERROR, IssueCodes.ILLEGAL_CLASS_INSTANTIATION, message, getExpression(), XbasePackage.Literals.XCONSTRUCTOR_CALL__CONSTRUCTOR, -1, null); result.accept(diagnostic); return false; }
@Override public void convertResourceDiagnostic(Diagnostic diagnostic, Severity severity, IAcceptor<Issue> acceptor) { IssueImpl issue = new Issue.IssueImpl(); issue.setSyntaxError(diagnostic instanceof XtextSyntaxDiagnostic); issue.setSeverity(severity); issue.setLineNumber(diagnostic.getLine()); issue.setColumn(diagnostic.getColumn()); issue.setMessage(diagnostic.getMessage()); if (diagnostic instanceof org.eclipse.xtext.diagnostics.Diagnostic) { org.eclipse.xtext.diagnostics.Diagnostic xtextDiagnostic = (org.eclipse.xtext.diagnostics.Diagnostic) diagnostic; issue.setOffset(xtextDiagnostic.getOffset()); issue.setLength(xtextDiagnostic.getLength()); } if (diagnostic instanceof AbstractDiagnostic) { AbstractDiagnostic castedDiagnostic = (AbstractDiagnostic)diagnostic; issue.setUriToProblem(castedDiagnostic.getUriToProblem()); issue.setCode(castedDiagnostic.getCode()); issue.setData(castedDiagnostic.getData()); } issue.setType(CheckType.FAST); acceptor.accept(issue); }
@Override public void doSignal(List<Diagnostic> errors, int cursorColumn, int cursorLine) { for (Diagnostic e : errors) { if (e instanceof AbstractDiagnostic) { AbstractDiagnostic error = (AbstractDiagnostic) e; int errorLine = error.getLine(); int errorBegin = error.getColumn(); int errorLength = error.getLength(); if (errorLine != cursorLine) { return; } doSignal(cursorColumn, cursorLine, errorBegin, errorLength); } } oldColumn = cursorColumn; oldLine = cursorLine; }
@Override public Collection<AbstractDiagnostic> getQueuedDiagnostics() { List<AbstractDiagnostic> result = Lists.newArrayList(); for(IResolvedTypes delegate: this) { result.addAll(delegate.getQueuedDiagnostics()); } return result; }
public void addDiagnostics(final Resource resource) { if (resource instanceof XtextResource) { if (((XtextResource) resource).isValidationDisabled()) return; } class DiagnosticAcceptor implements IAcceptor<AbstractDiagnostic> { @Override public void accept(/* @Nullable */ AbstractDiagnostic diagnostic) { if (diagnostic instanceof EObjectDiagnosticImpl) { Severity severity = ((EObjectDiagnosticImpl) diagnostic).getSeverity(); if (severity == Severity.ERROR) { resource.getErrors().add(diagnostic); } else if (severity == Severity.WARNING) { resource.getWarnings().add(diagnostic); } } else { resource.getErrors().add(diagnostic); } } } DiagnosticAcceptor acceptor = new DiagnosticAcceptor(); addQueuedDiagnostics(acceptor); addLinkingDiagnostics(acceptor); addTypeDiagnostics(acceptor); }
protected void addTypeDiagnostics(IAcceptor<? super AbstractDiagnostic> acceptor) { for(Map.Entry<XExpression, List<TypeData>> entry: basicGetExpressionTypes().entrySet()) { XExpression expression = entry.getKey(); if (!isPropagatedType(expression)) addTypeDiagnostic(expression, mergeTypeData(expression, entry.getValue(), false, false), acceptor); } }
@Override protected boolean validateArity(IAcceptor<? super AbstractDiagnostic> result) { if (getFeatureCall() instanceof XFeatureCall) { XExpression implicitReceiver = getImplicitReceiver(); if (implicitReceiver instanceof XFeatureCall) { JvmIdentifiableElement feature = ((XFeatureCall) implicitReceiver).getFeature(); if (feature instanceof JvmType && !getState().isInstanceContext()) { return false; } } } return super.validateArity(result); }
protected boolean validateTypeArgumentConformance(IAcceptor<? super AbstractDiagnostic> result) { if (getTypeArgumentConformanceFailures(result) == 0) { // TODO use early exit computation List<XExpression> arguments = getSyntacticArguments(); for(int i = 0; i < arguments.size(); i++) { XExpression argument = arguments.get(i); if (isDefiniteEarlyExit(argument)) { XExpression errorOn = getExpression(); String message = "Unreachable code."; EStructuralFeature errorFeature = null; if (i < arguments.size() - 1) { errorOn = arguments.get(i + 1); } else { errorFeature = getDefaultValidationFeature(); if (errorOn instanceof XBinaryOperation) { message = "Unreachable code. The right argument expression does not complete normally."; } else { message = "Unreachable code. The last argument expression does not complete normally."; } } AbstractDiagnostic diagnostic = new EObjectDiagnosticImpl( Severity.ERROR, IssueCodes.UNREACHABLE_CODE, message, errorOn, errorFeature, -1, null); result.accept(diagnostic); return false; } } } else { return false; } return true; }
protected boolean validateUnhandledExceptions(IAcceptor<? super AbstractDiagnostic> result) { if (getFeature() instanceof JvmExecutable) { JvmExecutable executable = (JvmExecutable) getFeature(); if (getUnhandledExceptionSeverity(executable) != Severity.IGNORE) { if (!executable.getExceptions().isEmpty()) { return validateUnhandledExceptions(executable, result); } } } return true; }
public void addDiagnostic(AbstractDiagnostic diagnostic) { if (diagnostics == null) { diagnostics = Sets.newLinkedHashSet(); } if (!diagnostics.add(diagnostic)) { throw new IllegalStateException("Duplicate diagnostic: " + diagnostic); } }
/** * Memorize the position and issue code of each resource error that appears in the file. * * @param root * root node of the model to be analyzed */ private void memorizeResourceErrors(final EObject root) { for (AbstractDiagnostic ad : Iterables.filter(root.eResource().getErrors(), AbstractDiagnostic.class)) { StringBuilder sb = new StringBuilder("Unexpected error: '"); sb.append(ad.getMessage()); sb.append(DOT_AND_LINEBREAK); memorizeErrorOnPosition(ad.getOffset(), sb.toString()); } }
@Override public boolean validate(IAcceptor<? super AbstractDiagnostic> result) { return true; }
@Override public Collection<AbstractDiagnostic> getQueuedDiagnostics() { return Collections.emptyList(); }
@Override public boolean validate(IAcceptor<? super AbstractDiagnostic> result) { // nothing to do return true; }
@Override public void addDiagnostic(AbstractDiagnostic diagnostic) { for (int i = 0; i < components.length; i++) { components[i].addDiagnostic(diagnostic); } }
@Override public boolean validate(IAcceptor<? super AbstractDiagnostic> result) { // no op return true; }
@Override public void addDiagnostic(AbstractDiagnostic diagnostic) { resolvedTypes.addDiagnostic(diagnostic); }
@Override public boolean validate(IAcceptor<? super AbstractDiagnostic> result) { Candidate candidate = getPrimaryCandidate(); if (candidate.validate(result)) { StringBuilder messageBuilder = new StringBuilder("Ambiguous ").append(getSyntaxDescriptions()).append(".\n"); messageBuilder.append("The ").append(getFeatureTypeName()).append("s"); Iterator<AbstractPendingLinkingCandidate<?>> iter = candidates.iterator(); boolean first = true; while(iter.hasNext()) { AbstractPendingLinkingCandidate<?> next = iter.next(); if (!first) { if (iter.hasNext()) { messageBuilder.append(","); } else { messageBuilder.append(" and"); } } else { first = false; } messageBuilder.append("\n\t"); if (!next.getDeclaredTypeParameters().isEmpty()) { messageBuilder.append(next.getFeatureTypeParametersAsString(true)).append(' '); } JvmIdentifiableElement feature = next.getFeature(); messageBuilder.append(feature.getSimpleName()); messageBuilder.append(next.getFeatureParameterTypesAsString()); String declarator = getDeclaratorSimpleName(feature); if (declarator != null) { messageBuilder.append(" in ").append(declarator); } } if (candidates.size() == 2) { messageBuilder.append("\nboth match."); } else { messageBuilder.append("\nall match."); } AbstractDiagnostic diagnostic = new EObjectDiagnosticImpl(Severity.ERROR, IssueCodes.AMBIGUOUS_FEATURE_CALL, messageBuilder.toString(), getExpression(), getFeatureToMark(), -1, getDiagnosticData()); result.accept(diagnostic); return false; } return false; }
protected void mergeQueuedDiagnostics(ResolvedTypes parent) { Collection<AbstractDiagnostic> diagnostics = super.getQueuedDiagnostics(); for(AbstractDiagnostic diagnostic: diagnostics) { parent.addDiagnostic(diagnostic); } }
@Override public List<AbstractDiagnostic> getQueuedDiagnostics() { List<AbstractDiagnostic> result = Lists.newArrayList(super.getQueuedDiagnostics()); result.addAll(parent.getQueuedDiagnostics()); return result; }
@Override public void addDiagnostic(AbstractDiagnostic diagnostic) { getParent().addDiagnostic(diagnostic); }
@Override public void addDiagnostic(AbstractDiagnostic diagnostic) { delegate.addDiagnostic(diagnostic); }
protected void addLinkingDiagnostics(IAcceptor<? super AbstractDiagnostic> acceptor) { Map<XExpression, IApplicableCandidate> candidates = basicGetLinkingMap(); for(IApplicableCandidate candidate: candidates.values()) { candidate.validate(acceptor); } }
protected void addQueuedDiagnostics(IAcceptor<? super AbstractDiagnostic> acceptor) { for(AbstractDiagnostic diagnostic: getQueuedDiagnostics()) { acceptor.accept(diagnostic); } }
@Override protected int getTypeArgumentConformanceFailures(/* @Nullable */ IAcceptor<? super AbstractDiagnostic> acceptor) { return 0; }
protected boolean validateUnhandledExceptions(JvmExecutable executable, IAcceptor<? super AbstractDiagnostic> result) { TypeParameterSubstitutor<?> substitutor = createArgumentTypeSubstitutor(); List<LightweightTypeReference> unhandledExceptions = null; List<LightweightTypeReference> expectedExceptions = getState().getExpectedExceptions(); ITypeReferenceOwner referenceOwner = getState().getReferenceOwner(); outer: for(JvmTypeReference typeReference: executable.getExceptions()) { LightweightTypeReference exception = referenceOwner.toLightweightTypeReference(typeReference); LightweightTypeReference resolvedException = substitutor.substitute(exception); if (resolvedException.isSubtypeOf(Throwable.class) && !resolvedException.isSubtypeOf(RuntimeException.class) && !resolvedException.isSubtypeOf(Error.class)) { for (LightweightTypeReference expectedException : expectedExceptions) { if (expectedException.isAssignableFrom(resolvedException)) { continue outer; } } if (unhandledExceptions == null) { unhandledExceptions = Lists.newArrayList(resolvedException); } else { unhandledExceptions.add(resolvedException); } } } if (unhandledExceptions != null) { String message = null; int count = unhandledExceptions.size(); if (count > 1) { message = String.format("Unhandled exception types %s and %s", IterableExtensions.join(unhandledExceptions.subList(0, count - 1), ", "), unhandledExceptions.get(count - 1)); } else { message = String.format("Unhandled exception type %s", unhandledExceptions.get(0).getHumanReadableName()); } String[] data = new String[unhandledExceptions.size() + 1]; for(int i = 0; i < data.length - 1; i++) { LightweightTypeReference unhandled = unhandledExceptions.get(i); data[i] = EcoreUtil.getURI(unhandled.getType()).toString(); } data[data.length - 1] = EcoreUtil.getURI(getExpression()).toString(); AbstractDiagnostic diagnostic = new EObjectDiagnosticImpl( getUnhandledExceptionSeverity(executable), IssueCodes.UNHANDLED_EXCEPTION, message, getExpression(), getDefaultValidationFeature(), -1, data); result.accept(diagnostic); return false; } return true; }
@Override public Collection<AbstractDiagnostic> getQueuedDiagnostics() { if (diagnostics == null) return Collections.emptyList(); return diagnostics; }
@Override public Collection<AbstractDiagnostic> getQueuedDiagnostics() { return delegate().getQueuedDiagnostics(); }
/** * Adds the given diagnostic to the current state. If this state is later discarded in favor * of a better solution, the diagnostic is discarded, too. */ void addDiagnostic(AbstractDiagnostic diagnostic);