/** * general top-level test: - invalid statements for StaticPolyfillModules. Constraints 140 (restrictions on * static-polyfilling) IDE-1735 */ @Check public void checkVariableStatement(Statement statement) { EObject con = statement.eContainer(); if (con instanceof Script) { // top-level elements will be checked only. Script script = (Script) con; if (!isContainedInStaticPolyfillModule(script)) { return; } // FunctionDeclarations have finer grained check in own validator. if (statement instanceof FunctionDeclaration) return; // it is a static polyfill module addIssue(getMessageForPOLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES(), statement, POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES); } }
/** * Constraints 3 and 4.2 */ @Check public void checkN4TypeDeclaration(N4TypeDeclaration n4TypeDeclaration) { if (isNotChecked(n4TypeDeclaration)) { return; } // quick exit: if (Character.isUpperCase(n4TypeDeclaration.getName().charAt(0))) { return; } if (holdsTypeNameNotIndistinguishable(n4TypeDeclaration, "getter/setter", GETTER_SETTER) // && holdsTypeNameNotIndistinguishable(n4TypeDeclaration, "access modifier", ACCESS_MODIFIERS) // && holdsTypeNameNotIndistinguishable(n4TypeDeclaration, "boolean literal", BOOLEAN_LITERALS) // && holdsTypeNameNotIndistinguishable(n4TypeDeclaration, "base type", BASE_TYPES) // && holdsTypeNameNotIndistinguishable(n4TypeDeclaration, "keyword", languageHelper.getECMAKeywords()) && holdsDoesNotStartWithLowerCaseLetter(n4TypeDeclaration)) { // error messages are created with in constraint validation } }
/** * Constraints 4.1 */ @Check public void checkN4MemberDeclaration(N4MemberDeclaration n4Member) { if (isNotChecked(n4Member)) { return; } if ( // IDEBUG-304 allow member names to be keywords // holdsNameMayNotBeConfusedWith(n4Member, "keyword", KEYWORDS) // // && holdsDoesNotEqualWithConstructor(n4Member) // && holdsNameMayNotBeConfusedWith(n4Member, "future reserved word", FUTURE_RESERVED_WORDS) // && holdsNameMayNotBeConfusedWith(n4Member, "boolean literal", BOOLEAN_LITERALS) // && // (!(n4Member instanceof Variable) // avoid redundant checks && holdsDoesNotStartWithUpperCaseLetter(n4Member) // && holdsNoTypeNameOrNameEqualsType(n4Member) // && holdsDoesNotContainDiscouragedCharacter(n4Member) // && holdsNameMayNotBeConfusedWith(n4Member, "access modifier", ACCESS_MODIFIERS) // )) { // error messages are created with in constraint validation } }
/** * Constraints 4.3 */ @Check public void checkVariable(Variable variable) { if (isNotChecked(variable)) { return; } if (holdsDoesNotStartWithDollarSign(variable) // && holdsDoesNotEqualWithConstructor(variable) // && holdsStartWithLowercaseLetter(variable) // && holdsNameMayNotBeConfusedWith(variable, "access modifier", ACCESS_MODIFIERS) // && holdsNoTypeNameOrNameEqualsType(variable) // && holdsDoesNotContainDiscouragedCharacter(variable)) { // error messages are created with in constraint validation } }
@Check public void checkFecha(final Restaurante restaurante) { try { SimpleDateFormat formateadorFecha = new SimpleDateFormat("dd-MM-yyyy"); Date fechaDada = formateadorFecha.parse(restaurante.getFecha()); Calendar fechaActual = Calendar.getInstance(); Date _time = fechaActual.getTime(); boolean _greaterThan = (fechaDada.compareTo(_time) > 0); if (_greaterThan) { this.error("La fecha tiene que ser igual o menor que la actual", RestaurantePackage.Literals.RESTAURANTE__FECHA, RestauranteValidator.FECHA_INVALIDA); } } catch (Throwable _e) { throw Exceptions.sneakyThrow(_e); } }
/** * Check that there is no overlap between the fields exported by a class and its parents. * * @param context * model to check */ @Check public void checkOverlap(final ExportModel context) { UniquenessJavaValidationHelper<Attribute> helper = new UniquenessJavaValidationHelper<Attribute>(NameFunctions.fromFeature(ExportPackage.Literals.ATTRIBUTE__ATTRIBUTE), getMessageAcceptor()); for (Export export : context.getExports()) { for (Export candidate : context.getExports()) { if (export.getType() != candidate.getType() && candidate.getType().isSuperTypeOf(export.getType())) { for (Attribute attribute : helper.findDuplicates(Iterables.concat(export.getAttributes(), candidate.getAttributes()))) { if (attribute.eContainer() == export) { error("Overlap duplicate found: " + attribute.getAttribute().getName(), attribute, ExportPackage.Literals.ATTRIBUTE__ATTRIBUTE, null); } } } } } }
/** * Checks that Check names are unique. A Check name may only occur once in a Check Catalog. * * @param catalog * the check catalog */ @Check public void checkCheckNamesAreUnique(final CheckCatalog catalog) { Function<com.avaloq.tools.ddk.check.check.Check, QualifiedName> function = new Function<com.avaloq.tools.ddk.check.check.Check, QualifiedName>() { @Override public QualifiedName apply(final com.avaloq.tools.ddk.check.check.Check from) { return QualifiedName.create(from.getName()); // no need to create a fully qualified name with check catalog here, it is only used for // comparing check instances } }; UniquenessJavaValidationHelper<com.avaloq.tools.ddk.check.check.Check> helper = // new UniquenessJavaValidationHelper<com.avaloq.tools.ddk.check.check.Check>(function, getMessageAcceptor()) { @Override public String getMessage(final com.avaloq.tools.ddk.check.check.Check duplicate) { return NLS.bind("Duplicate Check name: {0}", duplicate.getName()); //$NON-NLS-1$ } }; final Iterable<com.avaloq.tools.ddk.check.check.Check> allChecksWithName = Iterables.filter(catalog.getAllChecks(), new Predicate<com.avaloq.tools.ddk.check.check.Check>() { @Override public boolean apply(final com.avaloq.tools.ddk.check.check.Check input) { return input.getName() != null; } }); helper.errorOnDuplicates(allChecksWithName, locationInFileProvider::getIdentifierFeature, IssueCodes.DUPLICATE_CHECK); }
@Check public void checkTypeParameterNotUsedInStaticContext(JvmTypeReference ref) { if(ref.getType() instanceof JvmTypeParameter) { JvmTypeParameter typeParameter = (JvmTypeParameter) ref.getType(); if (!(typeParameter.getDeclarator() instanceof JvmOperation) || !isTypeParameterOfClosureImpl(ref)) { EObject currentParent = logicalContainerProvider.getNearestLogicalContainer(ref); while(currentParent != null) { if(currentParent == typeParameter.eContainer()) return; else if(isStaticContext(currentParent)) error("Cannot make a static reference to the non-static type " + typeParameter.getName(), ref, TypesPackage.Literals.JVM_PARAMETERIZED_TYPE_REFERENCE__TYPE, -1, STATIC_ACCESS_TO_INSTANCE_MEMBER); currentParent = currentParent.eContainer(); } } } }
/** * Checks that the interface referenced by a fingerprint is defined. * * @param context * export to check */ @Check public void checkFingerprintInterfaceDefined(final Export context) { if (context.isFingerprint() || context.isResourceFingerprint()) { ExportModel model = EObjectUtil.eContainer(context, ExportModel.class); Interface match = null; for (Interface iface : model.getInterfaces()) { if (iface.getType().isSuperTypeOf(context.getType())) { match = iface; break; } } if (match == null) { error("No matching interface specification declared", context.isFingerprint() ? ExportPackage.Literals.EXPORT__FINGERPRINT : ExportPackage.Literals.EXPORT__RESOURCE_FINGERPRINT); } } }
/** * Checks that no rule declares override when there is no corresponding inherited rule. * * @param model * the model */ @Check public void checkIllegalOverride(final FormatConfiguration model) { Iterable<Rule> overrideRules = Iterables.filter(model.getRules(), IS_OVERRIDE); Iterable<Rule> overrideableRules = Lists.newArrayList(); FormatConfiguration extendedModel = model.getExtendedFormatConfiguration(); if (extendedModel != null && !extendedModel.eIsProxy()) { overrideableRules = collectRules(extendedModel); } Map<AbstractRule, GrammarRule> overrideableAbstractRuleMap = Maps.newHashMap(); for (GrammarRule rule : Iterables.filter(overrideableRules, GrammarRule.class)) { overrideableAbstractRuleMap.put(TARGET_RULE.apply(rule), rule); } // Check GrammarRules for (GrammarRule overrideRule : Iterables.filter(overrideRules, GrammarRule.class)) { if (!overrideableAbstractRuleMap.containsKey(TARGET_RULE.apply(overrideRule))) { error(OVERRIDE_ILLEGAL_MESSAGE, overrideRule, FormatPackage.Literals.GRAMMAR_RULE__TARGET_RULE, OVERRIDE_ILLEGAL_CODE); } } // Check WildcardRule if (!Iterables.isEmpty(Iterables.filter(overrideRules, WildcardRule.class)) && Iterables.isEmpty(Iterables.filter(overrideableRules, WildcardRule.class))) { error(OVERRIDE_ILLEGAL_MESSAGE, Iterables.filter(overrideRules, WildcardRule.class).iterator().next(), null, OVERRIDE_ILLEGAL_CODE); } }
@Check void checkNullSafeFeatureCallWithPrimitives(XMemberFeatureCall featureCall) { if (featureCall.isNullSafe()) { if (getActualType(featureCall.getMemberCallTarget()).isPrimitive()) { error("Cannot use null-safe feature call on primitive receiver", featureCall, Literals.XMEMBER_FEATURE_CALL__NULL_SAFE, NULL_SAFE_FEATURE_CALL_ON_PRIMITIVE); return; } LightweightTypeReference type = getActualType(featureCall); if (type.isPrimitive() && isValueExpectedRecursive(featureCall)) { addIssue("Null-safe call of primitive-valued feature " + featureCall.getConcreteSyntaxFeatureName() + ", default value "+ getDefaultValue(type) +" will be used", featureCall, NULL_SAFE_FEATURE_CALL_OF_PRIMITIVE_VALUED_FEATURE); } } }
/** * Checks that the default severity is within given severity range. There must not be a conflict such * that the severity range defines severities do not contain the default. * <p> * Note that this check works even if {@link #checkSeverityRangeOrder(com.avaloq.tools.ddk.check.check.Check)} is violated. * </p> * * @param check * the check */ @Check public void checkDefaultSeverityInRange(final com.avaloq.tools.ddk.check.check.Check check) { if (check.getSeverityRange() == null) { return; // only applicable if both range and default severity given } final SeverityRange range = check.getSeverityRange(); final SeverityKind minSeverity = SeverityKind.get(Math.min(range.getMinSeverity().getValue(), range.getMaxSeverity().getValue())); final SeverityKind maxSeverity = SeverityKind.get(Math.max(range.getMinSeverity().getValue(), range.getMaxSeverity().getValue())); if (check.getDefaultSeverity().compareTo(minSeverity) < 0 || check.getDefaultSeverity().compareTo(maxSeverity) > 0) { List<String> issueCodes = Lists.newArrayList(); SeverityKind temp = minSeverity; while (temp != null && temp.compareTo(maxSeverity) <= 0) { issueCodes.add(temp.getName()); temp = SeverityKind.get(temp.getValue() + 1); } String[] codes = issueCodes.toArray(new String[issueCodes.size()]); error(Messages.CheckJavaValidator_DEFAULT_SEVERITY_NOT_IN_RANGE, check, CheckPackage.Literals.CHECK__DEFAULT_SEVERITY, IssueCodes.DEFAULT_SEVERITY_NOT_IN_RANGE, issueCodes.isEmpty() ? null // NOPMD : codes); } }
@Check public void checkTypeGuardsOrder(XSwitchExpression expression) { if (isIgnored(IssueCodes.UNREACHABLE_CASE)) { return; } ITypeReferenceOwner owner = new StandardTypeReferenceOwner(getServices(), expression); List<LightweightTypeReference> previousTypeReferences = new ArrayList<LightweightTypeReference>(); for (XCasePart casePart : expression.getCases()) { JvmTypeReference typeGuard = casePart.getTypeGuard(); if (typeGuard == null) { continue; } LightweightTypeReference actualType = owner.toLightweightTypeReference(typeGuard); if (actualType == null) { continue; } if (isHandled(actualType, previousTypeReferences)) { addIssue("Unreachable code: The case can never match. It is already handled by a previous condition.", typeGuard, IssueCodes.UNREACHABLE_CASE); continue; } if (casePart.getCase() == null) { previousTypeReferences.add(actualType); } } }
@Check public void checkTypeGuardsOrderWithGenerics(XSwitchExpression expression) { if (isIgnored(IssueCodes.UNREACHABLE_CASE)) { return; } ITypeReferenceOwner owner = new StandardTypeReferenceOwner(getServices(), expression); List<LightweightTypeReference> previousTypeReferences = new ArrayList<LightweightTypeReference>(); for (XCasePart casePart : expression.getCases()) { JvmTypeReference typeGuard = casePart.getTypeGuard(); if (typeGuard == null) { continue; } LightweightTypeReference typeReference = owner.toLightweightTypeReference(typeGuard); LightweightTypeReference actualType = typeReference.getRawTypeReference(); if (actualType == null || typeReference == actualType) { continue; } if (isHandled(actualType, previousTypeReferences)) { addIssue("Unreachable code: The case can never match. It is already handled by a previous condition (with the same type erasure).", typeGuard, IssueCodes.UNREACHABLE_CASE); continue; } if (casePart.getCase() == null) { previousTypeReferences.add(actualType); } } }
@Check public void checkCatchClausesOrder(XTryCatchFinallyExpression expression) { ITypeReferenceOwner owner = new StandardTypeReferenceOwner(getServices(), expression); List<LightweightTypeReference> previousTypeReferences = new ArrayList<LightweightTypeReference>(); for (XCatchClause catchClause : expression.getCatchClauses()) { LightweightTypeReference actualTypeReference = owner.toLightweightTypeReference(catchClause.getDeclaredParam().getParameterType()); if (actualTypeReference == null) { continue; } if (isHandled(actualTypeReference, previousTypeReferences)) { error("Unreachable code: The catch block can never match. It is already handled by a previous condition.", catchClause.getDeclaredParam().getParameterType(), null, IssueCodes.UNREACHABLE_CATCH_BLOCK); continue; } previousTypeReferences.add(actualTypeReference); } }
@Check public void checkOperandTypesForTripleEquals(XBinaryOperation binaryOperation) { if(isTripleEqualsOperation(binaryOperation)){ LightweightTypeReference left = getActualType(binaryOperation.getLeftOperand()); LightweightTypeReference right = getActualType(binaryOperation.getRightOperand()); if(left.isArray() != right.isArray()) { if (left.isArray()) { if (right.isAny() || right.isType(Object.class) || right.isType(Serializable.class) || right.isType(Cloneable.class)) { return; } } else { if (left.isAny() || left.isType(Object.class) || left.isType(Serializable.class) || left.isType(Cloneable.class)) { return; } } error("Incompatible operand types " + left.getHumanReadableName() + " and " + right.getHumanReadableName(), null, INVALID_OPERAND_TYPES); } } }
/** * Check that extended configuration's grammar is compatible. * * @param model * the model */ @Check public void checkExtendedGrammarCompatible(final FormatConfiguration model) { FormatConfiguration extendedModel = model.getExtendedFormatConfiguration(); if (extendedModel == null || extendedModel.eIsProxy()) { return; } if (!extendedModel.getTargetGrammar().eIsProxy()) { List<Grammar> grammars = Lists.newArrayList(model.getTargetGrammar()); grammars.addAll(model.getTargetGrammar().getUsedGrammars()); for (Grammar grammar : grammars) { if (extendedModel.getTargetGrammar().getName().equals(grammar.getName())) { return; } } } error("Extended format configuration has incompatible grammar", FormatPackage.Literals.FORMAT_CONFIGURATION__EXTENDED_FORMAT_CONFIGURATION, EXTENDED_GRAMMAR_INCOMPATIBLE_CODE); }
@Check public void checkNotMultipleBounds(JvmWildcardTypeReference typeRef) { List<JvmTypeConstraint> constraints = typeRef.getConstraints(); if (constraints.size() >= 2) { int upperBounds = 0; int lowerBounds = 0; for(int i = 0; i < constraints.size(); i++) { JvmTypeConstraint constraint = constraints.get(i); if (constraint.eClass() == TypesPackage.Literals.JVM_UPPER_BOUND) { upperBounds++; if (upperBounds > 1) { error("Invalid type constraint. Cannot use multiple upper bounds in wildcards.", typeRef, TypesPackage.Literals.JVM_CONSTRAINT_OWNER__CONSTRAINTS, i, IssueCodes.INVALID_WILDCARD_CONSTRAINTS); return; } } else { lowerBounds++; if (lowerBounds > 1) { error("Invalid type constraint. Cannot use multiple lower bounds in wildcards.", typeRef, TypesPackage.Literals.JVM_CONSTRAINT_OWNER__CONSTRAINTS, i, IssueCodes.INVALID_WILDCARD_CONSTRAINTS); } } } } }
@Check public void checkTypeArgsAgainstTypeParameters(JvmParameterizedTypeReference typeRef) { JvmType type = typeRef.getType(); if(type instanceof JvmGenericType && !type.eIsProxy()) { int numTypeParameters = ((JvmGenericType) type).getTypeParameters().size(); if(typeRef.getArguments().size() > 0) { if (numTypeParameters == 0) { errorTypeIsNotGeneric(type, typeRef); } else if(numTypeParameters != typeRef.getArguments().size()) { StringBuilder message = new StringBuilder(64); message.append("Incorrect number of arguments for type "); message = proxyAwareUIStrings.appendTypeSignature(type, message); message.append("; it cannot be parameterized with arguments "); message = proxyAwareUIStrings.appendTypeArguments(typeRef, message); if (message != null) { error(message.toString(), IssueCodes.INVALID_NUMBER_OF_TYPE_ARGUMENTS, typeRef); } } } else if(numTypeParameters > 0) { warnRawType(type, typeRef); } } else if (type != null && !type.eIsProxy() && !typeRef.getArguments().isEmpty()) { errorTypeIsNotGeneric(type, typeRef); } }
@Check public void checkInvalidReturnExpression(XExpression expression) { final EReference contFeature = (EReference) expression.eContainingFeature(); final Map<EReference, EarlyExitKind> map = getDisallowedEarlyExitReferences(); if (map.containsKey(contFeature)) { EarlyExitKind exitKind = map.get(contFeature); List<XExpression> returns = newArrayList(); collectExits(expression, returns); for (XExpression expr : returns) { if (expr instanceof XReturnExpression && (exitKind == EarlyExitKind.RETURN || exitKind == EarlyExitKind.BOTH)) { error("A return expression is not allowed in this context.", expr, null, IssueCodes.INVALID_EARLY_EXIT); } if (expr instanceof XThrowExpression && (exitKind == EarlyExitKind.THROW || exitKind == EarlyExitKind.BOTH)) { error("A throw expression is not allowed in this context.", expr, null, IssueCodes.INVALID_EARLY_EXIT); } } } }
@Check public void checkUniqueName(final EObject root) { EObject _eContainer = root.eContainer(); boolean _tripleEquals = (_eContainer == null); if (_tripleEquals) { final Resource resource = root.eResource(); EObject _head = IterableExtensions.<EObject>head(resource.getContents()); boolean _equals = Objects.equal(_head, root); if (_equals) { final Consumer<JvmDeclaredType> _function = (JvmDeclaredType it) -> { this.doCheckUniqueName(it); }; Iterables.<JvmDeclaredType>filter(resource.getContents(), JvmDeclaredType.class).forEach(_function); } } }
/** * Checks that a userdata clause does not declare a name that is the same as that of a structural feature of the type. * A warning is emitted in the general case, and an error if the name already exported. * * @param context * the export section to check */ @Check public void checkUserDataNameAsFeature(final Export context) { for (UserData data : context.getUserData()) { for (EStructuralFeature feature : context.getType().getEAllStructuralFeatures()) { if (data.getName().equals(feature.getName())) { if (context.getAllEAttributes().contains(feature)) { error(data.getName() + " is already defined as field", data, ExportPackage.Literals.USER_DATA__NAME, null); } else { error(data.getName() + " has the same name as an existing feature", data, ExportPackage.Literals.USER_DATA__NAME, null); } } } } }
@Check public void checkFirstRule(Grammar g) { if (g.getRules().isEmpty()) return; AbstractRule firstRule = g.getRules().get(0); if (!(firstRule instanceof ParserRule)) { if (!containsAnyParserRule(g, new HashSet<Grammar>())) return; error( "The first rule must be a parser rule.", firstRule, XtextPackage.Literals.ABSTRACT_RULE__NAME, ValidationMessageAcceptor.INSIGNIFICANT_INDEX); } else if (GrammarUtil.isDatatypeRule((ParserRule) firstRule)) { if (!containsAnyParserRule(g, new HashSet<Grammar>())) return; error( "The first rule must be a parser rule, but is a data type rule.", firstRule, XtextPackage.Literals.ABSTRACT_RULE__NAME, ValidationMessageAcceptor.INSIGNIFICANT_INDEX); } }
/** * Checks that rules declare overrides when there is a corresponding inherited rule. * * @param model * the model */ @Check public void checkOverrideMissing(final FormatConfiguration model) { FormatConfiguration extendedModel = model.getExtendedFormatConfiguration(); if (extendedModel == null || extendedModel.eIsProxy()) { return; } Iterable<Rule> nonOverrideRules = Iterables.filter(model.getRules(), Predicates.not(IS_OVERRIDE)); Iterable<Rule> overriddenRules = collectRules(extendedModel); Map<AbstractRule, GrammarRule> localAbstractRuleMap = Maps.newHashMap(); for (GrammarRule rule : Iterables.filter(nonOverrideRules, GrammarRule.class)) { localAbstractRuleMap.put(TARGET_RULE.apply(rule), rule); } // Check GrammarRules for (GrammarRule overriddenRule : Iterables.filter(overriddenRules, GrammarRule.class)) { if (localAbstractRuleMap.containsKey(TARGET_RULE.apply(overriddenRule))) { GrammarRule localRule = localAbstractRuleMap.get(TARGET_RULE.apply(overriddenRule)); error(OVERRIDE_MISSING_MESSAGE, localRule, FormatPackage.Literals.GRAMMAR_RULE__TARGET_RULE, OVERRIDE_MISSING_CODE); } } // Check WildcardRule if (!Iterables.isEmpty(Iterables.filter(nonOverrideRules, WildcardRule.class)) && !Iterables.isEmpty(Iterables.filter(overriddenRules, WildcardRule.class))) { error(OVERRIDE_MISSING_MESSAGE, Iterables.filter(nonOverrideRules, WildcardRule.class).iterator().next(), null, OVERRIDE_MISSING_CODE); } }
@Check public void checkReferencedMetamodel(ReferencedMetamodel metamodel) throws ValueConverterException { if (metamodel.getEPackage() == null) return; String nsURI = metamodel.getEPackage().getNsURI(); List<GeneratedMetamodel> allGeneratedMetamodels = getInheritedGeneratedMetamodels(metamodel); String text = getUsedUri(metamodel); for (GeneratedMetamodel generatedMetamodel : allGeneratedMetamodels) { EPackage generatedPackage = generatedMetamodel.getEPackage(); if (generatedPackage != null && nsURI.equals((generatedPackage.getNsURI()))) { if (!text.equals(nsURI)) { addIssue("Metamodels that have been generated by a super grammar must be referenced by nsURI: " + nsURI, metamodel, XtextPackage.Literals.ABSTRACT_METAMODEL_DECLARATION__EPACKAGE, INVALID_PACKAGE_REFERENCE_INHERITED, nsURI); return; } return; } } checkExternalPackage(metamodel, text); }
@Check public void checkTerminalFragmentCalledFromTerminalRule(final RuleCall call) { if (call.getRule() != null && !call.getRule().eIsProxy()) { if (call.getRule() instanceof TerminalRule && ((TerminalRule) call.getRule()).isFragment()) { AbstractRule container = GrammarUtil.containingRule(call); if (!(container instanceof TerminalRule)) { getMessageAcceptor().acceptError( "Only terminal rules may use terminal fragments.", call, XtextPackage.Literals.RULE_CALL__RULE, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, null); } } } }
@Check public void checkGeneratedEnumIsValid(EnumLiteralDeclaration decl) { EnumRule rule = GrammarUtil.containingEnumRule(decl); if (!(rule.getType().getMetamodel() instanceof GeneratedMetamodel)) return; if (!(rule.getType().getClassifier() instanceof EEnum)) return; EEnum eEnum = (EEnum) rule.getType().getClassifier(); List<EnumLiteralDeclaration> declarations = EcoreUtil2.getAllContentsOfType(rule, EnumLiteralDeclaration.class); if (declarations.size() == eEnum.getELiterals().size()) return; for (EnumLiteralDeclaration otherDecl : declarations) { if (decl == otherDecl) { return; } if (otherDecl.getEnumLiteral() == decl.getEnumLiteral()) { if (!decl.getEnumLiteral().getLiteral().equals(decl.getLiteral().getValue())) addIssue("Enum literal '" + decl.getEnumLiteral().getName() + "' has already been defined with literal '" + decl.getEnumLiteral().getLiteral() + "'.", decl, XtextPackage.Literals.ENUM_LITERAL_DECLARATION__ENUM_LITERAL, DUPLICATE_ENUM_LITERAL); return; } } }
/** * Checks that the all local scope rules (i.e. excluding inherited rules) have a unique context (context type, reference, * guard). * * @param context * scoping section to check */ @Check public void checkScopeRuleUniqueness(final ScopeModel context) { final Map<String, ScopeRule> profileMap = Maps.newHashMap(); for (ScopeDefinition def : context.getScopes()) { for (ScopeRule rule : def.getRules()) { final Expression guard = rule.getContext().getGuard(); final String profile = ScopeUtil.getSignature(rule) + ":" + (guard != null ? serializer.serialize(guard) : ""); //$NON-NLS-1$ //$NON-NLS-2$ final ScopeRule other = profileMap.get(profile); if (other != null) { errorOnDuplicate(rule, other, Messages.duplicatedScopeRule, ScopePackage.Literals.SCOPE_RULE__CONTEXT); } else { profileMap.put(profile, rule); } } } }
/** * Checks that an issue expression provides all required bindings. * * @param expression * the expression */ @Check public void checkIssuedBindings(final XIssueExpression expression) { if (generatorExtensions.issuedCheck(expression) == null) { return; } String message = generatorExtensions.issuedCheck(expression).getMessage(); if (Strings.isEmpty(message)) { return; } try { int boundParameters = expression.getMessageParameters().size(); int requiredBindings = new MessageFormat(message).getFormatsByArgumentIndex().length; if (boundParameters != requiredBindings) { error(NLS.bind(Messages.CheckJavaValidator_ISSUED_BINDINGS, requiredBindings, boundParameters), CheckPackage.Literals.XISSUE_EXPRESSION__MESSAGE_PARAMETERS, IssueCodes.ISSUED_BINDINGS); } // CHECKSTYLE:OFF } catch (IllegalArgumentException e) { // CHECKSTYLE:ON // do nothing here, because we can have potentially wrong messages given to MessageFormat, e.g. "{}" } }
/** * Verifies that all referenced extensions can be found. * * @param model * export model to check */ @Check public void checkExtensions(final ExportModel model) { ResourceManager resourceManager = null; if (Platform.isRunning()) { IXtendXpandProject project = Activator.getExtXptModelManager().findProject(ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(model.eResource().getURI().toPlatformString(true))).getProject()); if (project != null) { resourceManager = new XpandPluginExecutionContext(project).getResourceManager(); } } else { resourceManager = new ResourceManagerDefaultImpl(); } if (resourceManager == null) { return; } for (Extension ext : model.getExtensions()) { final Resource res = resourceManager.loadResource(ext.getExtension(), XtendFile.FILE_EXTENSION); if (res == null) { error(NLS.bind("Extension ''{0}'' not found", ext.getExtension()), ext, ExportPackage.Literals.EXTENSION__EXTENSION, null); } } }
@Check public void checkOppositeReferenceUsed(Assignment assignment) { Severity severity = getIssueSeverities(getContext(), getCurrentObject()).getSeverity(BIDIRECTIONAL_REFERENCE); if (severity == null || severity == Severity.IGNORE) { // Don't perform any check if the result is ignored return; } EClassifier classifier = GrammarUtil.findCurrentType(assignment); if (classifier instanceof EClass) { EStructuralFeature feature = ((EClass) classifier).getEStructuralFeature(assignment.getFeature()); if (feature instanceof EReference) { EReference reference = (EReference) feature; if (reference.getEOpposite() != null && !(reference.isContainment() || reference.isContainer())) { addIssue("The feature '" + assignment.getFeature() + "' is a bidirectional reference." + " This may cause problems in the linking process.", assignment, XtextPackage.eINSTANCE.getAssignment_Feature(), BIDIRECTIONAL_REFERENCE); } } } }
/** * Checks that all variable declarations contained in const statement (expressed by means of a variable statement) * contain an initializer expression. * * IDEBUG-214 */ @Check public void checkVariableStatement(VariableStatement variableStatement) { if (variableStatement.getVarStmtKeyword() == VariableStatementKeyword.CONST) { variableStatement.getVarDecl().stream().forEach(varDecl -> holdsConstHasInitializer(varDecl)); } }
/** * Checks modifiers. */ @Check private boolean checkModifiers(ModifiableElement elem) { return holdsNoInvalidOrDuplicateModifiers(elem) && holdsNotMoreThanOneAccessModifier(elem) && holdsCorrectOrder(elem); }
/** * Checks that no "with" is used and that list of implemented interfaces is separated with commas and not with * keywords. These checks (with some warnings created instead of errors) should help the transition from roles to * interfaces. However, they may be useful later on as well, e.g., if an interface is manually refactored into a * class or vice versa. * <p> * Note that "with" is used in Dart for roles, so maybe it is useful to have a user-friendly message instead of a * parser error. */ @Check public void checkClassDefinition(N4ClassDefinition n4ClassDefinition) { holdsNoKeywordInsteadOfComma(n4ClassDefinition); ICompositeNode node = NodeModelUtils.findActualNodeFor(n4ClassDefinition); ILeafNode keywordNode = findSecondLeafWithKeyword(n4ClassDefinition, "{", node, "extends", false); if (keywordNode != null) { TClass tclass = n4ClassDefinition.getDefinedTypeAsClass(); if (tclass == null) { return; // avoid consequential errors } if (StreamSupport.stream(tclass.getImplementedInterfaceRefs().spliterator(), false).allMatch( superTypeRef -> superTypeRef.getDeclaredType() instanceof TInterface)) { List<? extends IdentifiableElement> interfaces = StreamSupport.stream( tclass.getImplementedInterfaceRefs().spliterator(), false) .map(ref -> (TInterface) (ref.getDeclaredType())).collect(Collectors.toList()); String message = getMessageForSYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP( validatorMessageHelper.description(tclass), "extend", "interface" + (interfaces.size() > 1 ? "s " : " ") + validatorMessageHelper.names(interfaces), "implements"); addIssue(message, n4ClassDefinition, keywordNode.getTotalOffset(), keywordNode.getLength(), SYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP); } } }
/** * Ensures that a catch variable has not type annotation. This is supported by the parser to enable better error * messages. * * @see "Spec, 9.1.8" * @see <a href="https://github.com/NumberFour/n4js/issues/179">GHOLD-179</a> */ @Check public void checkCatchVariable(CatchVariable catchVariable) { if (catchVariable.getDeclaredTypeRef() != null) { addIssue(getMessageForAST_CATCH_VAR_TYPED(), catchVariable, N4JSPackage.eINSTANCE.getTypedElement_DeclaredTypeRef(), AST_CATCH_VAR_TYPED); } }
/** * Composed check for {@link EnumLiteralDeclaration}. * * @param n4EnumDeclaration * whose literals will be validated */ @Check public void checkEnumLiterals(N4EnumDeclaration n4EnumDeclaration) { Set<String> builtInEnumMembersNames = findBuiltInN4EnumMembers(n4EnumDeclaration); internalCheckNotInStaticPolyfillModule(n4EnumDeclaration, this); n4EnumDeclaration .getLiterals() .stream() .filter(it -> it.getName() != null) .collect(Collectors.groupingBy(N4EnumLiteral::getName)) .forEach( (name, literals) -> { // reduce number of issues, not all checks may be triggered // check enum literals duplicates if (literals.size() > 1) { addIssue(getMessageForENM_DUPLICTAE_LITERALS(name), literals.get(0), N4JSPackage.Literals.N4_ENUM_LITERAL__NAME, ENM_DUPLICTAE_LITERALS); return;// one issue at the time! } // check enum literal name clash with meta property if (builtInEnumMembersNames.contains(name)) { addIssue(getMessageForENM_LITERALS_HIDE_META(name), literals.get(0), N4JSPackage.Literals.N4_ENUM_LITERAL__NAME, ENM_LITERALS_HIDE_META); } }); }
/** * A top-level arrow function can't include uses of <code>arguments</code> and <code>this</code> as they lack an * outer lexical context that would provide bindings for them. */ @Check public void checkTopLevelLambda(ArrowFunction arrowFun) { if (LambdaUtils.isTopLevelLambda(arrowFun)) { rejectUsagesOfThisInTopLevelLambda(arrowFun); } }
@Check public void raiseSalary(Employee employee) { if (employee.getSalary() < 10000) { int newSalary = (10000 + employee.getSalary() * 2); //warning("Name should start with a capital", MyDslPackage.Literals.GREETING__NAME); //error("You should raise the salary to: " + newSalary, IOIPackage.Literals.EMPLOYEE__SALARY); //warning(message, feature, code, issueData) warning("You should raise the salary to: " + newSalary, IOIPackage.Literals.EMPLOYEE__SALARY, SALARY_TOO_LOW, (new Integer(newSalary)).toString()); } }
@Check public void cutSalary(Employee employee) { if (employee.getSalary() > 10000) { int newSalary = (employee.getSalary() / 2); //warning("Name should start with a capital", MyDslPackage.Literals.GREETING__NAME); //error("You should raise the salary to: " + newSalary, IOIPackage.Literals.EMPLOYEE__SALARY); //warning(message, feature, code, issueData) warning("You should cut the salary to: " + newSalary, IOIPackage.Literals.EMPLOYEE__SALARY, SALARY_TOO_HIGH, (new Integer(newSalary)).toString()); } }
@Check public void checkFoto(final Producto producto) { if ((((!producto.getFoto().endsWith(".png")) && (!producto.getFoto().endsWith(".gif"))) && (!producto.getFoto().endsWith(".jpg")))) { this.warning("El nombre del archivo para la foto tiene una extensi�n no reconocida", RestaurantePackage.Literals.PRODUCTO__FOTO, RestauranteValidator.EXTENSION_INVALIDA); } }