-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
mmews
committed
Jul 16, 2024
1 parent
93dd352
commit b5d4582
Showing
4 changed files
with
279 additions
and
264 deletions.
There are no files selected for viewing
76 changes: 76 additions & 0 deletions
76
...pse.n4js/src/org/eclipse/n4js/validation/validators/StaticPolyfillValidatorExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/** | ||
* Copyright (c) 2016 NumberFour AG. | ||
* 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: | ||
* NumberFour AG - Initial API and implementation | ||
*/ | ||
package org.eclipse.n4js.validation.validators; | ||
|
||
import static org.eclipse.n4js.utils.N4JSLanguageUtils.isContainedInStaticPolyfillModule; | ||
import static org.eclipse.n4js.utils.N4JSLanguageUtils.isStaticPolyfill; | ||
import static org.eclipse.n4js.validation.IssueCodes.POLY_IMPLEMENTING_INTERFACE_NOT_ALLOWED; | ||
import static org.eclipse.n4js.validation.IssueCodes.POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES; | ||
|
||
import org.eclipse.emf.ecore.EObject; | ||
import org.eclipse.n4js.n4JS.ExportDeclaration; | ||
import org.eclipse.n4js.n4JS.FunctionDeclaration; | ||
import org.eclipse.n4js.n4JS.N4ClassDeclaration; | ||
import org.eclipse.n4js.n4JS.N4EnumDeclaration; | ||
import org.eclipse.n4js.n4JS.N4InterfaceDeclaration; | ||
import org.eclipse.n4js.n4JS.N4JSPackage; | ||
import org.eclipse.n4js.n4JS.Script; | ||
|
||
/** | ||
* Collecting special validation logic only related to static polyfill modules. IDE-1735 | ||
*/ | ||
public class StaticPolyfillValidatorExtension { | ||
|
||
/** §143 (Restriction on static-polyfilling): §143.1 only classes in staticPolyfillModule allowed. */ | ||
public static void internalCheckNotInStaticPolyfillModule(N4InterfaceDeclaration n4InterfaceDeclaration, | ||
N4JSInterfaceValidator host) { | ||
if (isContainedInStaticPolyfillModule(n4InterfaceDeclaration)) { | ||
host.addIssue(n4InterfaceDeclaration, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, | ||
POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES.toIssueItem()); | ||
} | ||
} | ||
|
||
/** §143 (Restriction on static-polyfilling): §143.1 only classes in staticPolyfillModule allowed. */ | ||
public static void internalCheckNotInStaticPolyfillModule(N4EnumDeclaration n4EnumDecl, N4JSEnumValidator host) { | ||
if (isContainedInStaticPolyfillModule(n4EnumDecl)) { | ||
host.addIssue(n4EnumDecl, N4JSPackage.Literals.N4_TYPE_DECLARATION__NAME, | ||
POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES.toIssueItem()); | ||
} | ||
} | ||
|
||
/** §143 (Restriction on static-polyfilling): §143.1 only classes in staticPolyfillModule allowed. */ | ||
public static void internalCheckNotInStaticPolyfillModule(FunctionDeclaration functionDeclaration, | ||
N4JSFunctionValidator host) { | ||
// top level functionDeclarations: | ||
EObject cont = functionDeclaration.eContainer(); | ||
while (cont instanceof ExportDeclaration) { | ||
cont = cont.eContainer(); | ||
} | ||
if (cont instanceof Script) { | ||
if (isContainedInStaticPolyfillModule(functionDeclaration)) { | ||
host.addIssue(functionDeclaration, N4JSPackage.Literals.FUNCTION_DECLARATION__NAME, | ||
POLY_STATIC_POLYFILL_MODULE_ONLY_FILLING_CLASSES.toIssueItem()); | ||
} | ||
} | ||
} | ||
|
||
/** §143 (Restriction on static-polyfilling): §143.4 P must not implement any interfaces */ | ||
public static void internalCheckPolyFilledClassWithAdditionalInterface(N4ClassDeclaration classDeclaration, | ||
N4JSClassValidator host) { | ||
if (isStaticPolyfill(classDeclaration)) { | ||
if (!classDeclaration.getImplementedInterfaceRefs().isEmpty()) { | ||
host.addIssue(classDeclaration, N4JSPackage.Literals.N4_CLASS_DEFINITION__IMPLEMENTED_INTERFACE_REFS, | ||
POLY_IMPLEMENTING_INTERFACE_NOT_ALLOWED.toIssueItem()); | ||
} | ||
} | ||
} | ||
|
||
} |
71 changes: 0 additions & 71 deletions
71
...se.n4js/src/org/eclipse/n4js/validation/validators/StaticPolyfillValidatorExtension.xtend
This file was deleted.
Oops, something went wrong.
203 changes: 203 additions & 0 deletions
203
....eclipse.n4js/src/org/eclipse/n4js/validation/validators/UnsupportedFeatureValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
/** | ||
* Copyright (c) 2016 NumberFour AG. | ||
* 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: | ||
* NumberFour AG - Initial API and implementation | ||
*/ | ||
package org.eclipse.n4js.validation.validators; | ||
|
||
import static org.eclipse.n4js.utils.N4JSLanguageUtils.isNonStaticPolyfill; | ||
import static org.eclipse.n4js.utils.N4JSLanguageUtils.isStaticPolyfill; | ||
import static org.eclipse.n4js.validation.IssueCodes.UNSUPPORTED; | ||
|
||
import org.eclipse.emf.ecore.EObject; | ||
import org.eclipse.emf.ecore.EStructuralFeature; | ||
import org.eclipse.n4js.n4JS.AnnotableElement; | ||
import org.eclipse.n4js.n4JS.Argument; | ||
import org.eclipse.n4js.n4JS.BindingPattern; | ||
import org.eclipse.n4js.n4JS.ExportDeclaration; | ||
import org.eclipse.n4js.n4JS.ExportableElement; | ||
import org.eclipse.n4js.n4JS.FormalParameter; | ||
import org.eclipse.n4js.n4JS.N4ClassDefinition; | ||
import org.eclipse.n4js.n4JS.N4ClassExpression; | ||
import org.eclipse.n4js.n4JS.N4JSPackage; | ||
import org.eclipse.n4js.n4JS.N4NamespaceDeclaration; | ||
import org.eclipse.n4js.n4JS.NamedElement; | ||
import org.eclipse.n4js.n4JS.NamespaceElement; | ||
import org.eclipse.n4js.n4JS.NewTarget; | ||
import org.eclipse.n4js.n4JS.PropertySpread; | ||
import org.eclipse.n4js.utils.ResourceType; | ||
import org.eclipse.n4js.validation.ASTStructureValidator; | ||
import org.eclipse.n4js.validation.AbstractN4JSDeclarativeValidator; | ||
import org.eclipse.n4js.validation.JavaScriptVariantHelper; | ||
import org.eclipse.xtext.nodemodel.util.NodeModelUtils; | ||
import org.eclipse.xtext.validation.Check; | ||
import org.eclipse.xtext.validation.EValidatorRegistrar; | ||
|
||
import com.google.inject.Inject; | ||
|
||
/** | ||
* Validations to show an error for unsupported language features, mostly ECMAScript6 features. These validations will | ||
* be removed over time once the corresponding features are implemented. | ||
*/ | ||
@SuppressWarnings("javadoc") | ||
public class UnsupportedFeatureValidator extends AbstractN4JSDeclarativeValidator { | ||
|
||
@Inject | ||
JavaScriptVariantHelper jsVariantHelper; | ||
|
||
/** | ||
* NEEEDED | ||
* | ||
* when removed check methods will be called twice once by N4JSValidator, and once by | ||
* AbstractDeclarativeN4JSValidator | ||
*/ | ||
@Override | ||
public void register(EValidatorRegistrar registrar) { | ||
// nop | ||
} | ||
|
||
@Check | ||
public void checkAnonymousDefaultExport(ExportableElement decl) { | ||
if (decl instanceof NamedElement) { | ||
if (((NamedElement) decl).getName() == null && decl.isExportedAsDefault()) { | ||
unsupported("anonymous default export", decl); | ||
} | ||
} | ||
} | ||
|
||
@Check | ||
public void checkSeparateExport(ExportDeclaration exportDecl) { | ||
if (exportDecl.getExportedElement() == null) { | ||
if (exportDecl.isDefaultExport() && exportDecl.getDefaultExportedExpression() != null) { | ||
unsupported( | ||
"exporting values (only declared classes, interfaces, enums, functions and variables can be exported)", | ||
exportDecl); | ||
} else { | ||
boolean isDTS = ResourceType.getResourceType(exportDecl) == ResourceType.DTS; | ||
if (!isDTS) { | ||
unsupported( | ||
"separate export statements (add keyword 'export' directly before a class, interface, enum, function or variable declaration)", | ||
exportDecl); | ||
} | ||
} | ||
} | ||
} | ||
|
||
// TODO when removing this method, remove flag 'classExpressionsAreAllowed' as well! | ||
@Check | ||
public void checkClassExpression(N4ClassExpression classExpr) { | ||
if (!classExpressionsAreAllowed) { | ||
if (classExpr.getName() != null) { | ||
unsupported("class expressions", classExpr, N4JSPackage.eINSTANCE.getN4ClassExpression_Name()); | ||
} else { | ||
unsupported("class expressions", classExpr, NodeModelUtils.getNode(classExpr).getOffset(), 5); // the | ||
// first | ||
// 5 | ||
// characters | ||
// are | ||
// always | ||
// the | ||
// 'class' | ||
// keyword | ||
} | ||
} | ||
} | ||
|
||
private static boolean classExpressionsAreAllowed = false; | ||
|
||
@Check | ||
public void checkNewTarget(NewTarget newTarget) { | ||
unsupported("new.target", newTarget); | ||
} | ||
|
||
@Check | ||
public void checkExtendsExpression(N4ClassDefinition classDef) { | ||
if (classDef.getSuperClassExpression() != null) { | ||
unsupported("extends <expression>", classDef, | ||
N4JSPackage.eINSTANCE.getN4ClassDefinition_SuperClassExpression()); | ||
} | ||
} | ||
|
||
@Check | ||
public void checkBindingPatternAsFpar(BindingPattern pattern) { | ||
if (pattern.eContainer() instanceof FormalParameter) { | ||
unsupported("destructuring patterns as formal parameter", pattern); | ||
} | ||
} | ||
|
||
/** | ||
* NOTE: in addition to the errors produced by this and the following method, spread operator in <em>array | ||
* literals</em> is also unsupported; but that is checked in | ||
* {@link ASTStructureValidator#validateSpreadInArrayLiteral(org.eclipse.n4js.n4JS.ArrayElement, org.eclipse.n4js.validation.ASTStructureDiagnosticProducer)} | ||
*/ | ||
@Check | ||
public void checkSpreadOperatorInNewAndCallExpressions(Argument argument) { | ||
if (argument.isSpread()) { | ||
unsupported("spread operator in new and call expressions (only allowed in array destructuring patterns)", | ||
argument, N4JSPackage.eINSTANCE.getArgument_Spread()); | ||
} | ||
} | ||
|
||
@Check | ||
public void checkSpreadOperatorInObjectLiteral(PropertySpread propertySpread) { | ||
unsupported("spread operator in object literals (only allowed in array destructuring patterns)", | ||
propertySpread); | ||
} | ||
|
||
@Check | ||
public void checkNamespaceOutsideN4JSD(N4NamespaceDeclaration namespace) { | ||
if (!jsVariantHelper.isExternalMode(namespace)) { | ||
EObject markElem = (namespace.eContainer() instanceof ExportDeclaration) ? namespace.eContainer() | ||
: namespace; | ||
unsupported("namespaces in n4js/n4jsx files", markElem); | ||
} | ||
} | ||
|
||
@Check | ||
public void checkPolyfillInNamespace(NamespaceElement elem) { | ||
if (elem instanceof AnnotableElement) { | ||
AnnotableElement anElem = (AnnotableElement) elem; | ||
if (elem.getNamespace() != null && (isStaticPolyfill(anElem) || isNonStaticPolyfill(anElem))) { | ||
unsupported("polyfills in namespaces", elem); | ||
} | ||
} | ||
} | ||
|
||
// ---------------------------------------------------------------------------------------------------------------- | ||
// UTILITY METHODS | ||
|
||
private void unsupported(String msg, EObject source) { | ||
unsupported(msg, source, null); | ||
} | ||
|
||
private void unsupported(String msg, EObject source, EStructuralFeature feature) { | ||
addIssue( | ||
source, feature, | ||
UNSUPPORTED.toIssueItem(msg)); | ||
} | ||
|
||
private void unsupported(String msg, EObject source, int offset, int length) { | ||
addIssue( | ||
source, | ||
offset, length, | ||
UNSUPPORTED.toIssueItem(msg)); | ||
} | ||
|
||
/** | ||
* Turns off unsupported feature validation for class expressions, invokes given function, and turns validation back | ||
* on (for testing of class expressions). | ||
*/ | ||
public static void allowClassExpressions(Runnable r) { | ||
try { | ||
classExpressionsAreAllowed = true; | ||
r.run(); | ||
} finally { | ||
classExpressionsAreAllowed = false; | ||
} | ||
} | ||
} |
Oops, something went wrong.