Skip to content

Commit

Permalink
a first experiment
Browse files Browse the repository at this point in the history
  • Loading branch information
LorenzoBettini committed Dec 18, 2023
1 parent 2b19d66 commit c490251
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import static org.eclipse.xtend.core.xtend.XtendPackage.Literals.*;
import static org.eclipse.xtext.xbase.XbasePackage.Literals.*;
import static org.eclipse.xtext.xbase.validation.IssueCodes.*;
import static org.eclipse.xtext.xbase.validation.IssueCodes.CYCLIC_INHERITANCE;
import static org.eclipse.xtext.xtype.XtypePackage.Literals.*;

import java.util.Iterator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
import org.eclipse.xtext.xbase.typesystem.util.RecursionGuard;
import org.eclipse.xtext.xbase.validation.ImplicitReturnFinder;
import org.eclipse.xtext.xbase.validation.ImplicitReturnFinder.Acceptor;
import org.eclipse.xtext.xbase.validation.JvmGenericTypeValidator;
import org.eclipse.xtext.xbase.validation.ProxyAwareUIStrings;
import org.eclipse.xtext.xbase.validation.UIStrings;
import org.eclipse.xtext.xtype.XComputedTypeReference;
Expand All @@ -166,7 +167,7 @@
* @author Holger Schill
* @author Stephane Galland
*/
@ComposedChecks(validators = { AnnotationValidation.class })
@ComposedChecks(validators = { AnnotationValidation.class, JvmGenericTypeValidator.class })
public class XtendValidator extends XbaseWithAnnotationsValidator {

@Inject
Expand Down Expand Up @@ -667,11 +668,6 @@ public void checkSuperTypes(XtendClass xtendClass) {
}
checkWildcardSupertype(xtendClass, implementedType, XTEND_CLASS__IMPLEMENTS, i);
}
JvmGenericType inferredType = associations.getInferredType(xtendClass);
if (inferredType != null && hasCycleInHierarchy(inferredType, Sets.<JvmGenericType> newHashSet())) {
error("The inheritance hierarchy of " + notNull(xtendClass.getName()) + " contains cycles",
XTEND_TYPE_DECLARATION__NAME, CYCLIC_INHERITANCE);
}
}

@Check
Expand All @@ -683,11 +679,6 @@ public void checkSuperTypes(XtendInterface xtendInterface) {
}
checkWildcardSupertype(xtendInterface, extendedType, XTEND_INTERFACE__EXTENDS, i);
}
JvmGenericType inferredType = associations.getInferredType(xtendInterface);
if(inferredType != null && hasCycleInHierarchy(inferredType, Sets.<JvmGenericType> newHashSet())) {
error("The inheritance hierarchy of " + notNull(xtendInterface.getName()) + " contains cycles",
XTEND_TYPE_DECLARATION__NAME, CYCLIC_INHERITANCE);
}
}

protected boolean isAnnotation(JvmType jvmType) {
Expand Down Expand Up @@ -750,24 +741,6 @@ else if (typeRef instanceof JvmParameterizedTypeReference) {
return false;
}

protected boolean hasCycleInHierarchy(JvmGenericType type, Set<JvmGenericType> processedSuperTypes) {
JvmDeclaredType container = type;
do {
if (processedSuperTypes.contains(container))
return true;
container = container.getDeclaringType();
} while (container != null);
processedSuperTypes.add(type);
for (JvmTypeReference superTypeRef : type.getSuperTypes()) {
if (superTypeRef.getType() instanceof JvmGenericType) {
if (hasCycleInHierarchy((JvmGenericType) superTypeRef.getType(), processedSuperTypes))
return true;
}
}
processedSuperTypes.remove(type);
return false;
}

@Check
public void checkDuplicateAndOverriddenFunctions(XtendTypeDeclaration xtendType) {
final JvmDeclaredType inferredType = associations.getInferredType(xtendType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ public class IssueCodes extends org.eclipse.xtext.validation.IssueCodes {
*/
public static final String INVALID_TRY_RESOURCE_TYPE = ISSUE_CODE_PREFIX + "invalid_try_resource_type";

/**
* @since 2.34
*/
public static final String CYCLIC_INHERITANCE = ISSUE_CODE_PREFIX + "cyclic_inheritance";

private IssueCodes() {
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*******************************************************************************
* Copyright (c) 2023 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.xtext.xbase.validation;

import static org.eclipse.xtext.util.Strings.*;
import static org.eclipse.xtext.xbase.validation.IssueCodes.*;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmGenericType;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.TypesPackage;
import org.eclipse.xtext.validation.AbstractDeclarativeValidator;
import org.eclipse.xtext.validation.Check;
import org.eclipse.xtext.xbase.jvmmodel.IJvmModelAssociations;
import org.eclipse.xtext.xtype.XtypePackage;

import com.google.inject.Inject;

/**
* @author Lorenzo Bettini - Initial contribution and API
* @author Sebastian Zarnekow - Author of the original Java code in XtendValidator extracted here.
*/
public class JvmGenericTypeValidator extends AbstractDeclarativeValidator {

This comment has been minimized.

Copy link
@szarnekow

szarnekow Dec 18, 2023

You might need to override isLanguageSpecific and return false from it.

This comment has been minimized.

Copy link
@szarnekow

szarnekow Dec 18, 2023

Hmm looking at the code, this doesn't seem to be the case.

This comment has been minimized.

Copy link
@szarnekow

szarnekow Dec 18, 2023

I think we're only validating the first element in the resource's contents list.

This comment has been minimized.

Copy link
@szarnekow

szarnekow Dec 18, 2023

See org.eclipse.xtext.xbase.annotations.validation.DerivedStateAwareResourceValidator.validate(Resource, CheckMode, CancelIndicator, IAcceptor<Issue>)

This comment has been minimized.

Copy link
@LorenzoBettini

LorenzoBettini Dec 18, 2023

Author Owner

So probably I should override the validate method getting the resource and call validate on each element that has a jvm model association

This comment has been minimized.

Copy link
@LorenzoBettini

LorenzoBettini Dec 18, 2023

Author Owner

Actually, the AbstractDeclarativeValidator does nor provide such a method to override...

@Inject
private IJvmModelAssociations associations;

@Override
protected List<EPackage> getEPackages() {
return List.of(TypesPackage.eINSTANCE, XtypePackage.eINSTANCE);
}

@Check
public void checkSuperTypes(JvmGenericType type) {
var primarySourceElement = associations.getPrimarySourceElement(type);
if (primarySourceElement != null && hasCycleInHierarchy(type, new HashSet<>())) {
error("The inheritance hierarchy of " + notNull(type.getSimpleName()) + " contains cycles",
getNameFeature(primarySourceElement), CYCLIC_INHERITANCE);
}
}

protected boolean hasCycleInHierarchy(JvmGenericType type, Set<JvmGenericType> processedSuperTypes) {
JvmDeclaredType container = type;
do {
if (processedSuperTypes.contains(container))
return true;
container = container.getDeclaringType();
} while (container != null);
processedSuperTypes.add(type);
for (JvmTypeReference superTypeRef : type.getSuperTypes()) {
if (superTypeRef.getType() instanceof JvmGenericType) {
if (hasCycleInHierarchy((JvmGenericType) superTypeRef.getType(), processedSuperTypes))
return true;
}
}
processedSuperTypes.remove(type);
return false;
}

protected EStructuralFeature getNameFeature(EObject object) {
return object.eClass().getEStructuralFeature("name");
}
}

0 comments on commit c490251

Please sign in to comment.